当前位置:首页>python>Python & Sqlite 工业数据库备份与恢复:从零搭建一套真正可靠的容灾体系

Python & Sqlite 工业数据库备份与恢复:从零搭建一套真正可靠的容灾体系

  • 2026-06-28 18:12:16
Python & Sqlite 工业数据库备份与恢复:从零搭建一套真正可靠的容灾体系

🏭 数据丢了,生产线才是真的停了

去年我接手一个化工厂的上位机改造项目,前任开发者留下来的系统跑了五年,SQLite数据库文件有将近12GB。某天夜班,工控机硬盘突发坏道,系统直接挂掉。运维打电话过来问我:备份在哪?

翻遍整台机器,没有。一条备份脚本都没有。

五年的设备运行记录、工艺参数历史、报警日志——全没了。那次事故最终导致工厂停产将近两天,损失不是我能估算的数字。

这件事给我的教训很深:备份不是"有空了再做"的事,是系统上线第一天就必须到位的基础设施。 工业场景尤其如此——设备数据往往不可再生,一旦丢失,没有任何办法补回来。

这篇文章,咱们就把工业SQLite数据库的备份与恢复这件事,从头到尾说清楚。代码全部可以直接跑,不是那种"示意性伪代码"。


🔍 工业备份的特殊挑战

普通Web应用的备份,停服、导出、完事。工业数据库不行。

原因有三个。第一,不能停服。 设备24小时上报数据,你不可能为了备份让PLC停止通信。第二,数据库文件可能很大。 跑了几年的工业数据库,几个GB到几十GB很正常,直接复制文件的时间窗口太长,期间数据库状态可能变化。第三,恢复时间要求苛刻。 工厂等不起,恢复必须快,最好能精确到某个时间点。

这三个约束,决定了工业备份策略必须比普通应用更精细。

SQLite提供了一个官方的热备份API——sqlite3_backup,Python的sqlite3模块直接封装了这个接口,叫做conn.backup()。它的核心优势是在数据库正常读写的同时完成备份,不需要锁表,不影响业务。这是工业场景备份的基础工具。


🚀 方案一:在线热备份,业务不停机

先把最基础的热备份封装好:

import sqlite3import osimport timeimport shutilfrom datetime import datetimefrom pathlib import PathclassIndustrialBackupManager:"""    工业数据库备份管理器    核心设计原则:备份过程对业务零干扰    """def__init__(self, source_db: str, backup_dir: str):self.source_db = source_dbself.backup_dir = Path(backup_dir)self.backup_dir.mkdir(parents=True, exist_ok=True)defhot_backup(self, pages_per_step: int = 100, sleep_ms: int = 10) -> str:"""        在线热备份 —— 数据库正常运行时安全复制        pages_per_step: 每步复制的页数,越小对业务影响越低        sleep_ms: 每步之间的休眠毫秒数,让出CPU给业务线程        返回: 备份文件路径        """        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')        backup_path = self.backup_dir / f"backup_{timestamp}.db"        source_conn = sqlite3.connect(self.source_db)        backup_conn = sqlite3.connect(str(backup_path))try:# progress_callback 每步都会被调用,可以在这里记录进度defprogress_callback(status, remaining, total):if total > 0:                    pct = (total - remaining) / total * 100print(f"\r备份进度: {pct:.1f}% ({total-remaining}/{total} pages)"                          end='', flush=True)            source_conn.backup(                backup_conn,                pages=pages_per_step,       # 每次复制100页                progress=progress_callback,                sleep=sleep_ms / 1000.0# 转换为秒            )print(f"\n热备份完成: {backup_path}")returnstr(backup_path)finally:            source_conn.close()            backup_conn.close()defverify_backup(self, backup_path: str) -> bool:"""        备份完整性验证 —— 备份了但没验证,等于没备份        SQLite的integrity_check会检查页校验和、索引一致性等        """try:            conn = sqlite3.connect(backup_path)            cursor = conn.cursor()            cursor.execute('PRAGMA integrity_check')            result = cursor.fetchone()            conn.close()            is_ok = result[0] == 'ok'            status = "✅ 完整"if is_ok elsef"❌ 损坏: {result[0]}"print(f"备份验证 [{Path(backup_path).name}]: {status}")return is_okexcept Exception as e:print(f"❌ 验证失败: {e}")returnFalse

pages_per_step这个参数值得多说一句。SQLite数据库由固定大小的页(默认4KB)组成,backup()每次复制pages页后会暂停sleep秒,让业务线程有机会继续写入。值设得越小,备份对业务的影响越低,但备份总时间也越长。工业场景里,我一般设100页 + 10ms休眠,在一台普通工控机上备份1GB数据库大约需要3~4分钟,业务完全无感知。


⏰ 方案二:定时备份 + 自动轮转,防止磁盘撑爆

热备份的接口有了,下一步是让它自动跑起来,并且管理好历史备份文件——不然时间一长,备份把磁盘吃满,又是另一种事故。

import threadingimport loggingfrom typing importOptionallogging.basicConfig(    level=logging.INFO,format='%(asctime)s [%(levelname)s] %(message)s',    handlers=[        logging.FileHandler('backup.log', encoding='utf-8'),        logging.StreamHandler()    ])classScheduledBackupService:"""    定时备份服务 —— 后台线程自动执行,主程序无需关心    支持:全量备份 + 自动清理过期文件    """def__init__(self, manager: IndustrialBackupManager,                 full_backup_interval: int = 3600,   # 全量备份间隔(秒),默认1小时                 max_backups: int = 72):              # 最多保留72个备份(3天)self.manager = managerself.full_interval = full_backup_intervalself.max_backups = max_backupsself._stop_event = threading.Event()self._thread: Optional[threading.Thread] = Nonedefstart(self):"""启动后台备份服务"""self._thread = threading.Thread(            target=self._backup_loop,            name='BackupService',            daemon=True# 主程序退出时自动结束        )self._thread.start()        logging.info("定时备份服务已启动")defstop(self):self._stop_event.set()ifself._thread:self._thread.join(timeout=30)        logging.info("定时备份服务已停止")def_backup_loop(self):whilenotself._stop_event.is_set():try:self._do_full_backup()self._rotate_old_backups()except Exception as e:                logging.error(f"备份任务异常: {e}", exc_info=True)# 等待下一次备份,期间可响应stop信号self._stop_event.wait(timeout=self.full_interval)def_do_full_backup(self):        logging.info("开始全量热备份...")        t0 = time.time()        backup_path = self.manager.hot_backup()        elapsed = time.time() - t0# 备份完立刻验证ifself.manager.verify_backup(backup_path):            size_mb = os.path.getsize(backup_path) / 1024 / 1024            logging.info(f"备份成功: {Path(backup_path).name} "f"({size_mb:.1f}MB, 耗时{elapsed:.1f}s)")else:            logging.error(f"备份文件损坏,已删除: {backup_path}")            os.remove(backup_path)def_rotate_old_backups(self):"""清理超出数量限制的旧备份,保留最新的N个"""        backups = sorted(self.manager.backup_dir.glob('backup_*.db'),            key=lambda p: p.stat().st_mtime,            reverse=True# 最新的排前面        )        to_delete = backups[self.max_backups:]for old_backup in to_delete:            old_backup.unlink()            logging.info(f"清理过期备份: {old_backup.name}")

这里有个细节——daemon=True让备份线程成为守护线程,主程序(上位机应用)退出时备份线程自动结束,不会出现"主程序关了备份线程还在跑"的僵尸进程问题。

踩坑预警:备份目录别和数据库文件放在同一块硬盘。硬盘坏了,数据库和备份一起没。备份的意义在于冗余,至少要放到不同的物理存储介质上——外接U盘、网络共享目录、甚至另一台机器的SMB共享都行。


🔄 方案三:增量备份思路,应对超大数据库

全量备份对于几百MB的数据库完全够用。但如果你的数据库已经长到10GB以上,每小时全量备份一次,既耗时又耗空间。这时候需要引入增量备份的思路。

SQLite本身没有原生的增量备份API,但我们可以借助WAL(Write-Ahead Log)文件来实现近似的增量效果:

import hashlibclassIncrementalBackupManager:"""    基于WAL的增量备份策略    原理:WAL文件记录了自上次checkpoint以来的所有变更    通过定期归档WAL文件,实现增量备份    """def__init__(self, source_db: str, backup_dir: str):self.source_db = source_dbself.wal_file = source_db + '-wal'self.backup_dir = Path(backup_dir)self.backup_dir.mkdir(parents=True, exist_ok=True)self._last_wal_hash = Nonedefarchive_wal_if_changed(self) -> bool:"""        检测WAL文件是否有新变更,有则归档        每5分钟调用一次,捕获高频写入场景下的增量数据        """ifnot os.path.exists(self.wal_file):returnFalse# WAL模式未开启,或无待提交事务        wal_size = os.path.getsize(self.wal_file)if wal_size == 0:returnFalse# 计算WAL文件哈希,判断是否有新内容        current_hash = self._file_hash(self.wal_file)if current_hash == self._last_wal_hash:returnFalse# 没有变化,跳过# 有变化,归档这份WAL快照        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')        archive_path = self.backup_dir / f"wal_archive_{timestamp}.wal"        shutil.copy2(self.wal_file, str(archive_path))self._last_wal_hash = current_hash        size_kb = wal_size / 1024        logging.info(f"WAL增量归档: {archive_path.name} ({size_kb:.1f}KB)")returnTruedefforce_checkpoint_and_backup(self, conn: sqlite3.Connection) -> str:"""        强制WAL checkpoint后做全量备份        建议每天深夜执行一次,作为基准快照        """# checkpoint:把WAL里的变更合并回主数据库文件        conn.execute('PRAGMA wal_checkpoint(TRUNCATE)')        conn.commit()        logging.info("WAL checkpoint完成,开始全量基准备份")        mgr = IndustrialBackupManager(self.source_db, str(self.backup_dir))return mgr.hot_backup()    @staticmethoddef_file_hash(filepath: str) -> str:        h = hashlib.md5()withopen(filepath, 'rb'as f:while chunk := f.read(65536):                h.update(chunk)return h.hexdigest()

这套策略的组合用法是:每天凌晨做一次全量基准备份 + 每5分钟归档一次WAL增量。恢复时,先恢复最近的全量备份,再按时间顺序重放WAL归档文件,就能把数据还原到任意5分钟粒度的时间点。


🛠️ 方案四:完整的恢复流程,才是备份的终点

备份做得再好,不会恢复等于白搭。很多团队平时备份认真,真出事了手忙脚乱,恢复操作把备份文件也搞坏了。

classRecoveryManager:"""    数据库恢复管理器    原则:恢复操作永远在副本上进行,原备份文件只读不动    """def__init__(self, backup_dir: str, target_db: str):self.backup_dir = Path(backup_dir)self.target_db = target_dbdeflist_available_backups(self) -> list:"""列出所有可用备份,按时间倒序"""        backups = []for f insorted(self.backup_dir.glob('backup_*.db'),                       key=lambda p: p.stat().st_mtime, reverse=True):            size_mb = f.stat().st_size / 1024 / 1024            mtime = datetime.fromtimestamp(f.stat().st_mtime)            backups.append({'path'str(f),'name': f.name,'size_mb'round(size_mb, 1),'time': mtime.strftime('%Y-%m-%d %H:%M:%S')            })return backupsdefrestore_from_backup(self, backup_path: str,                           create_safety_copy: bool = True) -> bool:"""        从指定备份文件恢复数据库        create_safety_copy: 恢复前先把当前数据库备份一份                           —— 万一恢复的备份也有问题,还能退回去        """        backup_path = Path(backup_path)ifnot backup_path.exists():            logging.error(f"备份文件不存在: {backup_path}")returnFalse# 第一步:验证备份文件完整性        logging.info("验证备份文件完整性...")        mgr = IndustrialBackupManager(str(backup_path), str(self.backup_dir))ifnot mgr.verify_backup(str(backup_path)):            logging.error("备份文件损坏,中止恢复")returnFalse# 第二步:把当前数据库做一个安全副本(如果存在的话)if create_safety_copy and os.path.exists(self.target_db):            safety_path = self.target_db + f".before_restore_{int(time.time())}"            shutil.copy2(self.target_db, safety_path)            logging.info(f"当前数据库已备份至: {safety_path}")# 第三步:用备份覆盖目标数据库# 注意:先复制到临时文件,再原子性重命名,避免复制到一半系统崩溃        tmp_path = self.target_db + '.tmp_restore'try:            shutil.copy2(str(backup_path), tmp_path)            os.replace(tmp_path, self.target_db)  # 原子操作# 清理WAL和SHM文件,避免旧的WAL干扰恢复后的数据库for ext in ['-wal''-shm']:                leftover = self.target_db + extif os.path.exists(leftover):                    os.remove(leftover)                    logging.info(f"清理残留文件: {leftover}")            logging.info(f"恢复成功: {backup_path.name} -> {self.target_db}")returnTrueexcept Exception as e:            logging.error(f"恢复失败: {e}")if os.path.exists(tmp_path):                os.remove(tmp_path)returnFalsedefrestore_latest(self) -> bool:"""一键恢复到最新备份——应急场景最常用"""        backups = self.list_available_backups()ifnot backups:            logging.error("没有找到任何备份文件")returnFalse        latest = backups[0]        logging.info(f"准备恢复最新备份: {latest['name']} "f"({latest['time']}{latest['size_mb']}MB)")returnself.restore_from_backup(latest['path'])

注意os.replace()这个调用——它在Windows上是原子操作(POSIX语义),确保即使恢复过程中断电,目标文件要么是旧的完整版本,要么是新的完整版本,不会出现半截文件。这个细节在工控机这种可能随时断电的环境里非常重要。


🔧 把所有东西串起来,一个完整的使用示例

if __name__ == '__main__':    SOURCE_DB = r'C:\IndustrialApp\data\production.db'    BACKUP_DIR = r'D:\Backups\production_db'# D盘,不同于数据库所在的C盘# 初始化备份管理器    backup_mgr = IndustrialBackupManager(SOURCE_DB, BACKUP_DIR)# 启动定时备份服务(每小时全量备份,保留3天)    scheduler = ScheduledBackupService(        manager=backup_mgr,        full_backup_interval=3600,        max_backups=72    )    scheduler.start()# 初始化恢复管理器(应急时用)    recovery_mgr = RecoveryManager(BACKUP_DIR, SOURCE_DB)# 模拟主程序运行(实际是你的上位机主循环)print("上位机系统运行中,备份服务在后台工作...")print("可用备份列表:")for b in recovery_mgr.list_available_backups()[:5]:print(f"  {b['time']}{b['name']}{b['size_mb']}MB")try:# 主循环...        time.sleep(7200)except KeyboardInterrupt:        scheduler.stop()print("系统正常退出")

💡 三句话带走的核心洞察

备份验证和备份本身同等重要——没有经过integrity_check验证的备份,只是一个你以为安全的文件。

工业场景的恢复操作永远先做安全副本,再执行覆盖,给自己留一条退路。

os.replace()的原子性是工控机断电保护的最后一道防线,别用shutil.copy直接覆盖目标文件。


📚 延伸方向

本文覆盖的是单机SQLite场景。如果你的工业系统在演进——比如从单机上位机升级为多节点数据采集平台——可以进一步研究:SQLite的复制扩展(如Litestream,支持实时流式备份到S3/MinIO)PostgreSQL的PITR(时间点恢复)机制,以及工业场景下的主备切换架构设计。备份策略会随着系统规模的增长而演进,但核心原则不变:冗余、验证、快速恢复。

欢迎在评论区分享你在工业项目里遇到过的数据备份问题,或者你现在用的是什么备份方案——不同场景下的实践经验,往往比文档更有参考价值。


标签#Python开发#SQLite备份#工业数据库#容灾恢复#性能优化

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-04 11:05:40 HTTP/2.0 GET : https://f.mffb.com.cn/a/487762.html
  2. 运行时间 : 0.115484s [ 吞吐率:8.66req/s ] 内存消耗:4,640.38kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=f2c19b7b9bf264ca3a10617bc2e37ac3
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000782s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000840s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000317s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000283s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000509s ]
  6. SELECT * FROM `set` [ RunTime:0.000187s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000630s ]
  8. SELECT * FROM `article` WHERE `id` = 487762 LIMIT 1 [ RunTime:0.001274s ]
  9. UPDATE `article` SET `lasttime` = 1783134340 WHERE `id` = 487762 [ RunTime:0.018881s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000373s ]
  11. SELECT * FROM `article` WHERE `id` < 487762 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000614s ]
  12. SELECT * FROM `article` WHERE `id` > 487762 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000499s ]
  13. SELECT * FROM `article` WHERE `id` < 487762 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.006743s ]
  14. SELECT * FROM `article` WHERE `id` < 487762 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.003877s ]
  15. SELECT * FROM `article` WHERE `id` < 487762 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001754s ]
0.117103s