ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

MoviePilot PostgreSQL 数据库配置与迁移实战指南

MoviePilot PostgreSQL 数据库配置与迁移实战指南 后端AI AgentMCP 服务AI 技能【免费下载链接】MoviePilotNAS媒体库自动化管理工具项目地址https://gitcode.com/gh_mirrors/mo/MoviePilot点击查看免费下载MoviePilot 作为 NAS 媒体库自动化管理工具默认使用 SQLite 存储订阅、下载历史、站点数据等核心数据同时从 v2.0 起完整支持 PostgreSQL 作为备选数据库后端。本指南以 docs/postgresql-setup.md 为主体结合仓库源码app/runtime/config.py、app/db/engine.py 等深入讲解数据库类型切换、连接参数、Unix Socket 连接、Docker 部署、SQLite↔PostgreSQL 双向迁移、备份恢复、性能优化与故障排查读完你可以独立完成 MoviePilot 数据库后端的替换与迁移。数据库类型选择与配置参数1. 数据库类型切换MoviePilot 通过DB_TYPE环境变量决定使用哪种数据库后端该配置位于config/app.env文件中# 使用 SQLite默认 DB_TYPEsqlite # 使用 PostgreSQL DB_TYPEpostgresql从源码看该开关是所有数据库相关配置的“总闸”。在 app/application/settings/contract.py 中所有DB_POSTGRESQL_*与DB_SQLITE_*前缀的运行时配置项都被声明为依赖DB_TYPE在 app/db/engine.py 中引擎构建函数_get_database_engine()也是依据DB_TYPE分流到 PostgreSQL 或 SQLite 的引擎工厂。默认值定义于 app/runtime/config.pyDB_TYPE: str sqlite即开箱即用无需任何数据库配置。2. PostgreSQL 连接参数当DB_TYPEpostgresql时以下配置生效默认值取自 app/runtime/config.py# PostgreSQL 主机地址默认 localhost DB_POSTGRESQL_HOSTlocalhost # PostgreSQL 端口使用 Unix Socket 时可留空默认 5432 DB_POSTGRESQL_PORT5432 # PostgreSQL 数据库名默认 moviepilot DB_POSTGRESQL_DATABASEmoviepilot # PostgreSQL 用户名默认 moviepilot DB_POSTGRESQL_USERNAMEmoviepilot # PostgreSQL 密码默认 moviepilot DB_POSTGRESQL_PASSWORDmoviepilot # PostgreSQL 连接池大小默认 10文档示例为 20 DB_POSTGRESQL_POOL_SIZE20 # PostgreSQL 连接池溢出数量默认 50文档示例为 30 DB_POSTGRESQL_MAX_OVERFLOW30值得注意的是仓库当前源码中的默认值是DB_POSTGRESQL_POOL_SIZE10、DB_POSTGRESQL_MAX_OVERFLOW50文档示例给出的 20/30 属于推荐调优值。连接池参数最终会映射到 SQLAlchemyQueuePool的pool_size与max_overflow见 app/db/engine.py请结合你的数据库max_connections与业务并发量综合设置。连接 URL 的组装集中在Settings.DB_POSTGRESQL_URL()方法app/runtime/config.py用户名与密码会经过 URL 编码数据库名同样被转义避免特殊字符破坏连接串。同步连接使用postgresql://前缀异步连接自动切换为postgresqlasyncpg://见 app/db/engine.py。3. Unix Socket 连接如果 PostgreSQL 通过 Unix Socket 暴露可以把DB_POSTGRESQL_HOST设置为套接字目录DB_TYPEpostgresql DB_POSTGRESQL_HOST/var/run/postgresql DB_POSTGRESQL_PORT DB_POSTGRESQL_DATABASEmoviepilot DB_POSTGRESQL_USERNAMEmoviepilot DB_POSTGRESQL_PASSWORDmoviepilot如需显式指定 socket 端口也可以保留DB_POSTGRESQL_PORT程序会生成带host/path/to/socket查询参数的 PostgreSQL URL。源码层面的判定逻辑位于 app/runtime/config.py 的DB_POSTGRESQL_SOCKET_MODE属性只要DB_POSTGRESQL_HOST以/开头即视为 Socket 路径。此时 URL 会改写为postgresql://user:pass/dbname?host/path/to/socketport...的查询参数形式app/runtime/config.py日志中连接目标也会显示为socket /path/to/socket。仓库的 tests/test_postgresql_socket_config.py 专门验证了这一 Socket 模式下的 URL 生成行为。Docker 部署使用外部 PostgreSQL如果您想使用外部的 PostgreSQL 服务确保外部 PostgreSQL 服务已启动并可访问设置环境变量指向外部服务DB_TYPEpostgresql DB_POSTGRESQL_HOSTyour-postgresql-host DB_POSTGRESQL_PORT5432 DB_POSTGRESQL_DATABASEmoviepilot DB_POSTGRESQL_USERNAMEyour-username DB_POSTGRESQL_PASSWORDyour-password连接建立成功后启动日志中会出现如下提示由 app/db/engine.py 打印PostgreSQL database connected to host:5432/moviepilotMoviePilot 将 PostgreSQL 以独立模块PostgreSQLModule纳入模块系统app/modules/postgresql/init.py其test()方法会在DB_TYPEpostgresql时对数据库治理层发起连通性测试返回“PostgreSQL连接失败xxx”或成功。你可以在应用内的模块健康检查中使用这一能力验证外部数据库连通性。数据迁移从 SQLite 迁移到 PostgreSQL以在 Windows 下操作为例迁移分两个大阶段准备与建表、pgloader 数据搬运与收尾。阶段一准备与建表关闭 SQLite 的 WAL 模式如果此前已经开启并关闭 MoviePilot备份现有的 SQLite 数据库文件config/user.db按照上述要求修改配置为 PostgreSQL注意由于 SQLite 与 PostgreSQL 对部分字段的类型例如json类型定义不同请勿通过user.db在迁移阶段直接在空数据库的基础上创建表结构而应按照下一条要求通过 MoviePilot 的初始化自动创建正确的表结构只有在这种情况下迁移工具才能正确处理数据类型启动应用让 MoviePilot 自动创建表结构确认创建完成后关闭 MoviePilot使用如下 SQL 语句清理所有初始化完成的表数据只保留表结构避免默认的初始化数据干扰迁移TRUNCATE TABLE agentchat, agenttask, alembic_version, downloadfailure, downloadfiles, downloadhistory, mediaserveritem, message, passkey, plugindata, site, siteicon, sitestatistic, siteuserdata, subscribe, subscribehistory, systemconfig, transferhistory, user, userconfig, workflow RESTART IDENTITY CASCADE;阶段二pgloader 数据搬运安装 Java 21 或更新的版本并下载 dimitri/pgloader 中的 v4 版本 jar 包即pgloader.jar创建migrate.load文件并编辑如下内容。注意Windows 下本地.db文件路径引用需要有 3 个斜线userrequest表已经废弃是 v1 阶段的残留物下列配置文件将会自动去除LOAD DATABASE FROM sqlite:///X:/path/to/user.db INTO postgresql://moviepilot:your-passwordhost:5432/moviepilot WITH data only, reset sequences EXCLUDING TABLE NAMES LIKE userrequest SET work_mem TO 16MB, maintenance_work_mem TO 512MB CAST type integer to boolean when ( precision 1) ;使用java --enable-native-accessALL-UNNAMED -jar .\pgloader.jar .\migrate.load启动迁移。迁移过程中可能产生大量警告和报错主要与孤儿索引idx__PRIMARY相关形如WARN [main] pgloader.core - Primary Keys failed (skipping): ERROR: index idx__PRIMARY does not belong to table plugindata此类报错属预期现象可继续后续步骤清理孤儿索引DROP INDEX IF EXISTS idx__PRIMARY;修正 Alembic 版本号UPDATE alembic_version SET version_num d58298a0879f;阶段三修复自增序列由于 SQLite 与 PostgreSQL 的自增序列原理不同直接导入会出现冲突需手动更新自增序列问题背景SQLite 的 AUTOINCREMENT 不依赖独立序列对象数据行带着具体 id 值进入 PostgreSQL但 PostgreSQL 使用独立的 Sequence如plugindata_id_seq生成新 ID。迁移后 Sequence 仍停留在初始值如 1而表中已有 id10186 的数据导致新插入时报duplicate key value violates unique constraint。执行时机迁移完成后、应用启动前必做运行中报主键冲突时应急从备份恢复数据后建议做安全说明本脚本只读表内最大 id 并调整序列不修改任何数据行可重复执行。DO $$ DECLARE rec RECORD; seq_name TEXT; max_id BIGINT; tbl_full TEXT; fix_count INT : 0; err_count INT : 0; BEGIN RAISE NOTICE 开始扫描 public schema 下的自增序列...; -- 遍历 public schema 下所有带自增序列的列 -- 通过 pg_get_serial_sequence() 直接获取序列名不依赖 pg_depend兼容性好 FOR rec IN SELECT n.nspname AS schema_name, c.relname AS table_name, a.attname AS column_name FROM pg_class c JOIN pg_namespace n ON c.relnamespace n.oid JOIN pg_attribute a ON a.attrelid c.oid WHERE n.nspname public AND c.relkind r -- 只处理普通表排除视图/系统表 AND a.attnum 0 -- attnum 0 是系统隐藏列 AND NOT a.attisdropped -- 排除已删除但未清理的列 AND c.relname NOT LIKE pg_% -- 排除 PostgreSQL 系统表 AND c.relname NOT LIKE sql_% AND pg_get_serial_sequence( quote_ident(n.nspname) || . || quote_ident(c.relname), a.attname ) IS NOT NULL -- 只保留确实有自增序列关联的列 ORDER BY c.relname, a.attname LOOP BEGIN -- 构造带 schema 前缀的表名quote_ident 自动处理 user 等关键字 tbl_full : quote_ident(rec.schema_name) || . || quote_ident(rec.table_name); -- 获取该列当前最大值。COALESCE 处理空表无数据时返回 0 EXECUTE format(SELECT COALESCE(MAX(%I), 0) FROM %s, rec.column_name, tbl_full) INTO max_id; -- 获取序列完整名称含 schema seq_name : pg_get_serial_sequence(tbl_full, rec.column_name); -- 重置序列 -- 参数1: 序列名 -- 参数2: 重置到的值max_id 1空表时为 1 -- 参数3: is_called false表示 nextval() 下次直接返回该值不再递增 -- 效果下一条 INSERT 拿到的 id 正好是表中未使用的最小值 PERFORM setval(seq_name, max_id 1, false); RAISE NOTICE 已修复: %.% (列 %) - 序列 % 设为 % (表内最大 id %), rec.schema_name, rec.table_name, rec.column_name, seq_name, max_id 1, max_id; fix_count : fix_count 1; EXCEPTION WHEN OTHERS THEN -- 单表异常不阻断整体流程记录后继续下一张表 RAISE NOTICE 跳过 %.%: %, rec.schema_name, rec.table_name, SQLERRM; err_count : err_count 1; END; END LOOP; RAISE NOTICE 完成。修复 % 个序列跳过/错误 % 个。, fix_count, err_count; END $$;验证序列修复结果-- 验证查看所有序列当前值确认 last_value 大于对应表的最大 id SELECT sequencename, last_value FROM pg_sequences WHERE schemaname public ORDER BY sequencename;启动 MoviePilot如果迁移成功你应当在日志中看到类似下面的信息INFO: [moviepilot] 5b3355c964bb_2_2_0.py - 发现 21 个表需要检查序列 INFO: [moviepilot] a946dae52526_2_2_1.py - 开始PostgreSQL数据库userid字段迁移... INFO: [moviepilot] a946dae52526_2_2_1.py - PostgreSQL数据库userid字段迁移完成 INFO: [moviepilot] 41ef1dd7467c_2_2_2.py - SystemConfig 表去重操作已完成。 INFO: Started server process [129]这几条日志对应的正是仓库中的三个 PostgreSQL 相关迁移脚本5b3355c964bb_2_2_0.py负责将 SQLite 迁移过来的 Sequence 转换为 PostgreSQL 的 Identity见 database/versions/5b3355c964bb_2_2_0.py它会遍历发现的需要检查序列的表、读取序列当前最大值并把起始值提升到max_id 1与上面手动的setval修复思路一致a946dae52526_2_2_1.py负责 PostgreSQL 下userid字段的迁移41ef1dd7467c_2_2_2.py负责SystemConfig表的去重。也就是说即使手动步骤有遗漏应用启动时这些迁移脚本也会兜底修复部分序列与数据一致性问题——但手动执行 11 步的setval脚本仍是迁移完成后、应用启动前的必做动作。从 PostgreSQL 迁移到 SQLite导出 PostgreSQL 数据修改配置为 SQLite启动应用数据库表会自动创建导入数据到 SQLite数据备份PostgreSQL 数据备份PostgreSQL 数据存储在${CONFIG_DIR}/postgresql/目录中您可以通过以下方式进行备份1. 文件级备份# 备份整个PostgreSQL数据目录 tar -czf postgresql_backup_$(date %Y%m%d_%H%M%S).tar.gz config/postgresql/2. 数据库级备份# 进入容器 docker exec -it moviepilot bash # 使用pg_dump备份 pg_dump -h localhost -U moviepilot -d moviepilot /config/moviepilot_backup.sql # 或使用pg_dumpall备份所有数据库 pg_dumpall -h localhost -U moviepilot /config/all_databases_backup.sql3. 恢复数据# 恢复单个数据库 psql -h localhost -U moviepilot -d moviepilot /config/moviepilot_backup.sql # 恢复所有数据库 psql -h localhost -U moviepilot /config/all_databases_backup.sql除上述手工备份方式外MoviePilot 自身还内置了数据库自动备份能力app/runtime/config.pyDB_BACKUP_ENABLE开启后可按DB_BACKUP_CRON默认0 3 * * *即每天凌晨 3 点定时备份支持DB_BACKUP_RETENTION_DAYS保留天数默认 30与DB_BACKUP_MAX_COUNT保留份数默认 30双维度清理且DB_BACKUP_ON_UPGRADE默认开启会在检测到数据库需要结构迁移前自动创建恢复点。建议将自动备份与手工pg_dump结合双保险保障数据安全。性能优化PostgreSQL 优化建议连接池配置根据应用负载调整DB_POSTGRESQL_POOL_SIZE设置合适的DB_POSTGRESQL_MAX_OVERFLOW数据库配置调整shared_buffers配置work_mem设置合适的maintenance_work_mem索引优化为常用查询字段添加索引定期执行VACUUM和ANALYZE源码级的连接额度核算进阶MoviePilot 在连接池层面做了一层显式的连接额度核算app/db/engine.py同步池上限由DB_POSTGRESQL_POOL_SIZE DB_POSTGRESQL_MAX_OVERFLOW构成异步侧还叠加了DB_ASYNC_POOL_SIZE默认 5、DB_ASYNC_MAX_OVERFLOW默认 10与DB_ASYNC_FALLBACK_LIMIT默认 10见 app/runtime/config.py最后乘以 worker 数API_WORKERS得到理论峰值。启动时check_connection_budget()app/db/engine.py会执行SHOW max_connections与SHOW superuser_reserved_connections用数据库真实的连接上限而非猜测值对比理论峰值。若超限会输出错误日志并提示请调大max_connections或调小API_WORKERS/DB_POSTGRESQL_MAX_OVERFLOW/DB_ASYNC_MAX_OVERFLOW/DB_ASYNC_FALLBACK_LIMIT否则突发并发时可能出现TooManyConnectionsError。多 worker 部署时每个进程各持一份连接池合计需乘上 worker 数——这是容易踩坑的点。此外app/runtime/config.py 提供了DB_CONNECT_ARGSJSON 字典用于透传驱动级连接参数例如经 PgBouncer 事务模式接入时 asyncpg 需要{statement_cache_size: 0}该参数会原样并入create_engine/create_async_engine的connect_args。同步驱动方面free-threaded 解释器下会自动使用不会重新启用 GIL 的 psycopg 驱动app/db/engine.py。故障排除常见问题连接失败检查 PostgreSQL 服务是否启动验证连接参数是否正确确认网络连接和防火墙设置权限问题确保用户有足够的数据库权限检查pg_hba.conf配置性能问题监控连接池使用情况检查慢查询日志优化数据库配置日志查看PostgreSQL 相关日志可以在以下位置查看Docker 容器${CONFIG_DIR}/postgresql/logs/系统日志journalctl -u postgresql使用 doctor 快速定位数据库问题MoviePilot 内置的 doctor 检查项会针对 PostgreSQL 做专项诊断app/doctor/checks.py当DB_TYPEpostgresql但主机、库名、用户名等基本字段缺失时会报告PostgreSQL 配置不完整建议补齐后重启默认离线模式不会主动连接 PostgreSQL配置完整时仅提示“可使用moviepilot doctor --deep做 TCP 连通性探测”--deep模式下会对DB_POSTGRESQL_HOST:DB_POSTGRESQL_PORT做 TCP 端口连通性检查输出“PostgreSQL TCP 端口可连接/不可连接”若启动日志提示数据库连接失败可结合 doctor 结果检查 PostgreSQL 服务、网络和账号权限。你也可以通过 app/modules/postgresql/init.py 中PostgreSQLModule.test()返回的错误信息定位连接层问题如认证失败、主机不可达等。注意事项兼容性PostgreSQL 支持从 MoviePilot v2.0 开始备份建议定期备份数据库版本建议使用 PostgreSQL 12 或更高版本字符集确保使用 UTF-8 字符集参考资料本指南主体docs/postgresql-setup.md数据库配置项定义与默认值app/runtime/config.pyPostgreSQL 引擎构建与连接额度核算app/db/engine.pyPostgreSQL 模块与连通性测试app/modules/postgresql/init.pydoctor 数据库专项检查app/doctor/checks.py迁移期序列修复脚本database/versions/5b3355c964bb_2_2_0.py相关测试tests/test_postgresql_socket_config.py、tests/test_db_engine_postgresql.py、tests/test_database_index_migration.py赞分享后端AI AgentMCP 服务AI 技能【免费下载链接】MoviePilotNAS媒体库自动化管理工具项目地址https://gitcode.com/gh_mirrors/mo/MoviePilot点击查看免费下载相关推荐ImageProcessing100Wen性能优化指南Python vs C实现对比分析ImageProcessing100Wen性能优化指南Python vs C实现对比分析 想要在图像处理项目中获得极致性能吗ImageProcessin示例工程教程Wasp 生产环境数据库实战PostgreSQL 配置、迁移管理与连接Wasp 生产环境数据库实战PostgreSQL 配置、迁移管理与连接 本篇指南聚焦 Wasp 应用从本地开发走向线上部署时数据库侧的全部关键环节生产数据库Web框架后端前端CLI开发工具Create.js 键盘快捷键完整清单提升编辑效率的10个必备技巧Create.js 键盘快捷键完整清单提升编辑效率的10个必备技巧 Create.js 作为一款高效的内容编辑工具提供了丰富的键盘快捷键功能帮助开发者和内前端UI库/组件上一篇探索Tiny Heart一款轻量级的情感分析库下一篇VOFA 插件库使用教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表