LLDAP 数据库后端迁移实战:从 SQLite 平滑切换至 PostgreSQL / MySQL / MariaDB
后端认证鉴权【免费下载链接】lldapLight LDAP implementation项目地址https://gitcode.com/gh_mirrors/ll/lldap点击查看免费下载LLDAP 是一款轻量级 LDAP 实现其数据默认存储在 SQLite 数据库中适合中小规模部署但当你需要更高并发、更强的备份恢复能力或与既有数据库基础设施统一管理时就需要把数据从 SQLite 迁移到 PostgreSQL、MySQL 或 MariaDB。本文以 docs/database_migration.md 为骨架完整讲解建库 → 停机导出 → 数据清洗 → 导入 → 切换配置五步迁移流程并结合仓库源码create_schema命令实现、SQL 建表逻辑、数据库 URL 解析与官方辅助脚本scripts/sqlite_dump_commands.sh让你能安全、可回滚地完成数据库后端切换。迁移总体思路与适用前提迁移的本质是数据搬运 格式转换LLDAP 各数据库后端共享同一套表结构由 SQL 迁移逻辑统一维护因此只要目标数据库里建好空表再把旧库数据以 INSERT 语句的形式灌入即可。官方文档给出的迁移流程共五步在目标数据库上创建空 schema表结构停止/暂停 LLDAP导出既有数据针对目标数据库做数据清洗并非总是需要将数据导入目标库修改 LLDAP 配置指向新库并重启文档明确指出后续步骤假设你已经为 LLDAP 准备好了一个空数据库实例PostgreSQL 或 MySQL迁移前无需向其中预置任何表——表结构由 LLDAP 自己创建。小贴士如果目标是 PostgreSQL官方文档推荐优先考虑 pgloader 这类专门工具它可以从多种数据库自动迁移到 PostgreSQL本文的手工流程更适合 MySQL/MariaDB 或需要精细控制的情况。第一步在目标数据库创建 schemaLLDAP 提供了专用的 CLI 子命令create_schema它会连接目标数据库并初始化表结构。该命令的实现位于 server/src/main.rsasync fn create_schema_command(opts: RunOpts) - Result() { let config configuration::init(opts)?; let sql_pool setup_sql_tables(config.database_url).await?; info!(Schema created successfully.); ... }可以看到它复用了服务启动时相同的setup_sql_tables逻辑因此创建出的表结构与正式运行时完全一致。命令注册在 server/src/cli.rs子命令名为create_schema接收一个-d/--database-url参数对应环境变量LLDAP_DATABASE_URL。如果使用 Docker 部署推荐直接在正在运行的容器内执行这样能保证容器内网络可以访问到目标数据库docker exec -it LLDAP container name /app/lldap create_schema -d Target database url例如docker exec -it lldap /app/lldap create_schema -d postgres://lldap_user:passwordpostgres-server/lldap执行成功后日志会输出Schema created successfully.此时可以进入下一步。若失败请检查目标数据库连接串、权限需要建表权限以及网络连通性。schema 背后统一的建表逻辑从源码看LLDAP 各数据库后端共用 crates/sql-backend-handler/src/sql_tables.rs 中的init_table见该文件第 44 行起与一系列迁移语句例如用户表、组表、成员关系表、属性表等。其中groups表使用自增主键CREATE TABLE groups ( group_id INTEGER PRIMARY KEY, display_name TEXT );而metadata表专门记录 schema 版本version INTEGER用于启动时的自动迁移判定见 sql_tables.rs。这正是后续清洗步骤中需要特别处理groups.group_id自增序列的原因详见下文 PostgreSQL 小节。第二步导出既有数据停机导出导出的目标是生成一份只包含 INSERT 语句的 SQL 文件。有两类表需要排除metadata表它是 LLDAP 内部的 schema 版本管理表目标库已由create_schema建好无需迁移sqlite_sequence表仅当它存在时SQLite 的自增序列内部表。同时导出前务必停止/暂停 LLDAP文档明确指出如果 LLDAP 正处于写入状态某些数据库如 SQLite在 dump 时会直接报错。这与 SQLite 的写锁机制有关停机导出能保证数据快照的一致性。仓库提供了辅助脚本 scripts/sqlite_dump_commands.sh它按表输出.mode insert与select *命令配合 sqlite3 即可生成带INSERT INTO table VALUES (...)语句的 dump./sqlite_dump_commands.sh | sqlite3 /path/to/lldap/config/users.db /path/to/dump.sql脚本覆盖的表清单导出顺序即如下顺序users、groups、memberships、jwt_refresh_storage、jwt_storage、password_reset_tokens、group_attribute_schema、group_attributesuser_attribute_schema但排除内置的first_name、last_name、avatar三个属性它们由 LLDAP 在启动时自动重建无需迁移user_attributes用户的自定义属性值脚本开头还有一行.header on用于让 sqlite3 的.mode insert生成带列名的 INSERT 语句便于后续 sed 清洗时精确匹配表名。注意该脚本面向 SQLite 场景。若从 MySQL/PostgreSQL 迁移导出思路相同仅导出 INSERT 排除 metadata 表但导出命令需换成对应数据库的 dump 工具并同样先停止 LLDAP。第三步数据清洗SanitizeSQLite 导出的 INSERT 语句不一定能直接被 PostgreSQL/MySQL 接受差异主要集中在十六进制字符串语法PostgreSQL 与 SQLite 的 hex 字面量写法不同表名转义方式MySQL 用反引号而非双引号布尔值写法1/0与true/false的差异时间格式MariaDB 的 DATETIME 不支持时区偏移后缀事务包裹建议把全部 INSERT 包在一个事务里避免中途失败产生半截数据。官方针对三种目标数据库给出了三份sed -i清洗命令下面逐一说明。迁移到 PostgreSQLsed -i -r -e s/X([[:xdigit:]][^])/\\\x\\1/g \ -e :a; s/(INSERT INTO (user_attribute_schema|jwt_storage)\(.*\) VALUES\(.*),1([^]*\);)$/\1,true\3/; s/(INSERT INTO (user_attribute_schema|jwt_storage)\(.*\) VALUES\(.*),0([^]*\);)$/\1,false\3/; ta \ -e 1s/^/BEGIN;\n/ \ -e $aSELECT setval(pg_get_serial_sequence(\groups\, \group_id\), COALESCE((SELECT MAX(group_id) FROM groups), 1)); \ -e $aCOMMIT; /path/to/dump.sql这条命令依次做了四件事hex 格式转换把 SQLite 的XABCD形式转换为 PostgreSQL 的\xABCD形式g全局替换sed -i原地修改文件布尔值重写对user_attribute_schema与jwt_storage两张表的 INSERT把行尾的,1换成,true、,0换成,false:a; ...; ta循环确保替换到稳定为止。这两张表包含布尔列而 PostgreSQL 不接受整型1/0作为布尔值在文件头部插入BEGIN;将全部插入包进一个事务任何一条语句失败都可整体回滚文件尾部追加序列校正 COMMIT;groups.group_id在 PostgreSQL 中由序列serial生成直接插入显式 id 不会推进序列后续 LLDAP 新建组时会主键冲突。因此用setval把groups_group_id_seq调整到当前最大值。这与上文提到的groups表INTEGER PRIMARY KEY结构直接相关。迁移到 MySQLsed -i -r -e s/^INSERT INTO ?([a-zA-Z0-9_])?/INSERT INTO \1/ \ -e 1s/^/START TRANSACTION;\n/ \ -e $aCOMMIT; \ -e 1 i\SET FOREIGN_KEY_CHECKS 0; /path/to/dump.sqlMySQL 的差异点与处理表名反引号SQLite 生成的INSERT INTO groups (...)使用了双引号而 MySQL 需要用反引号转义表名。特别注意groups是 MySQL 的保留字不转义会直接报语法错误。该规则对全部表名生效事务包裹头部加START TRANSACTION;尾部加COMMIT;临时关闭外键检查第一行插入SET FOREIGN_KEY_CHECKS 0;避免按依赖顺序插入如先插 groups 再插 memberships时因外键约束报错导入完成后随COMMIT恢复默认行为。迁移到 MariaDBsed -i -r -e s/([^][0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{9})\00:00([^])/\1\2/g \ -e s/^INSERT INTO ?([a-zA-Z0-9_])?/INSERT INTO \1/ \ -e 1s/^/START TRANSACTION;\n/ \ -e $aCOMMIT; \ -e 1 i\SET FOREIGN_KEY_CHECKS 0; /path/to/dump.sqlMariaDB 与 MySQL 基本兼容但不支持 DATETIME 字符串上的时区偏移如2026-10-07T02:18:03.12345678900:00尾部的00:00因此先通过正则把形如...99999999900:00的时区后缀去掉再执行与 MySQL 相同的反引号、事务与外键处理。使用sed -i会直接改写原 dump 文件建议先对 dump.sql 做一次备份便于出错后重来。第四步导入目标数据库把清洗后的 dump 文件导入目标库官方给出了两种主流客户端的标准做法。导入 PostgreSQLpsql -d database -U username -W /path/to/dump.sql或使用-f参数指定文件-W会在连接时提示输入密码psql -d database -U username -W -f /path/to/dump.sql如果遇到报错常见原因有某行数据的格式仍未兼容可手动微调该行、导入中途失败导致部分数据进入因为有事务包裹整体回滚后修好 dump 重导即可、或序列未同步检查上一步的setval是否正确追加。导入 MySQLmysql -u username -p database /path/to/dump.sql如果出现错误官方建议两种处理路径手动调整 dump 中出问题的语句或者先在 LLDAP 界面/API 中修正对应数据再重新导出例如某条属性值格式异常直接在 LLDAP 里改掉后重新走一遍 dump 流程。第五步切换配置并重启导入成功后把 LLDAP 的数据库连接指向新库——注意必须与第一步创建 schema 时使用的 URL 完全一致。配置位置有两种等价方式配置文件中的database_url字段环境变量LLDAP_DATABASE_URL优先级覆盖配置文件。参考 lldap_config.docker_template.toml 中给出的 URL 格式## - postgres://postgres-user:passwordpostgres-server/my-database ## - mysql://mysql-user:passwordmysql-server/my-database # database_url sqlite:///data/users.db?moderwc # SQLite 默认 database_url postgres://lldap_user:passwordpostgres-server/lldap修改后重启 LLDAP并检查日志确认启动过程中没有数据库相关错误重点关注连接失败、表缺失、主键冲突等。启动正常后建议做一轮功能冒烟验证登录管理界面、查询用户列表、用 LDAP 客户端做一次 bind确认读写都正常。连接串解析的实现细节database_url在 server/src/database_string.rs 中被封装为DatabaseUrl类型它基于标准 URL 解析通过 URL 的 schemesqlite/postgres/mysql判断后端类型db_type()方法。该类型还做了密码脱敏处理——调试输出时密码会被替换为***PASSWORD***见该文件第 26-37 行避免日志泄露凭据。因此迁移切换后若日志中打印了连接串密码也会以掩码形式出现属于正常现象。迁移后的验证清单与回滚无论目标库是 PostgreSQL 还是 MySQL/MariaDB迁移完成后都建议按以下清单复核用户与组数量一致对比旧库与新库中users、groups、memberships的行数自定义属性完整确认user_attribute_schema非内置属性与user_attributes数据无丢失认证可用用任意用户执行一次 LDAP bind确认密码校验正常密码以加盐形式存储迁移过程不涉及密码解密直接搬运即可组创建正常新建一个测试组验证自增主键/序列没有冲突对应 PostgreSQL 的setval步骤是否生效JWT 会话jwt_storage、jwt_refresh_storage已迁移但若更换了jwt_secret/key_seed会话与密码校验会被重置请确认未误改相关配置。由于旧库在迁移前只是暂停而非销毁回滚非常简单把database_url改回旧库并重启即可。这也是官方流程先建新库、再切换设计的好处——确认新库完全正常前旧库始终是可用的退路。最后官方文档还提示更完整的端到端示例可参考仓库 CI 流程中的lldap-database-migration-test作业它会在构建流水线中实际执行建 schema → 导出 → 清洗 → 导入 → 切换的全过程是验证本文各命令可用性的最佳参考实现。赞分享后端认证鉴权【免费下载链接】lldapLight LDAP implementation项目地址https://gitcode.com/gh_mirrors/ll/lldap点击查看免费下载相关推荐Mailu 数据库后端切换指南从 SQLite 迁移到 PostgreSQL 与 MySQL/MariaDBMailu 数据库后端切换指南从 SQLite 迁移到 PostgreSQL 与 MySQL/MariaDB 导读 Mailu 是一套以 Docker 镜像形后端通信BTCPay Server 数据库迁移实战从 SQLite / MySQL 平滑迁移到 PostgreSQLBTCPay Server 数据库迁移实战从 SQLite / MySQL 平滑迁移到 PostgreSQL 导读 BTCPay Server 曾长期同时支持区块链金融科技后端LLDAP项目数据库迁移完整指南从SQLite到PostgreSQL/MySQLLLDAP项目数据库迁移完整指南从SQLite到PostgreSQL/MySQL 前言 在轻量级目录访问协议 LLDAP 项目的实际部署中随着业务规模的增长后端认证鉴权上一篇抖音内容下载新范式如何用开源工具构建个人数字资产库下一篇抖音批量下载器终极指南5分钟学会无水印视频保存技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

ts-jest 自定义 AST Transformer 完全指南:astTransformers 配置、编写与实战

ts-jest 自定义 AST Transformer 完全指南:astTransformers 配置、编写与实战

测试开发工具 【免费下载链接】ts-jest A Jest transformer with source map support that lets you use Jest to test projects written in TypeScript. 项目地址: https://gitcode.com/gh_mirrors/ts/ts-jest 点击查看 免费下载 astTransformers 是 ts-jest 提供…

2026/10/10 16:51:43 阅读更多 →
90DaysOfDevOps Day 83:Grafana 数据可视化实战——基于 kube-prometheus 与 Prometheus Operator 部署监控面板

90DaysOfDevOps Day 83:Grafana 数据可视化实战——基于 kube-prometheus 与 Prometheus Operator 部署监控面板

文档/教程 【免费下载链接】90DaysOfDevOps This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Pri…

2026/10/9 17:08:58 阅读更多 →
学校心理咨询聊天室毕设源码:小程序+SSM+MySQL全链路解析

学校心理咨询聊天室毕设源码:小程序+SSM+MySQL全链路解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 17:09:20 阅读更多 →

最新新闻

Rust性能优化实战:五个技巧榨干硬件性能

Rust性能优化实战:五个技巧榨干硬件性能

很多人聊 Rust 性能优化,第一反应是“这语言天生就快,还用得着调?”我最初也这么想,直到接手一个用 Rust 写的日志处理服务,在单机 8 核上处理一千万条日志要跑十几秒,调完之后压缩到两秒出头,C…

2026/10/13 16:37:10 阅读更多 →
5G智慧校园解决方案:云网端架构、专网组网与评审避坑指南

5G智慧校园解决方案:云网端架构、专网组网与评审避坑指南

简介:这份PPT围绕5G智慧校园解决方案展开,面向教育信息化管理者、智慧校园规划人员及行业方案设计师,系统梳理了教育信息化从1.0“三通两平台”迈向2.0“三全两高一大”的政策背景与现实需求,并针对教学质量提升、资源优质共享、校…

2026/10/13 16:37:10 阅读更多 →
Python声纹识别实战:EcapaTdnn/ResNetSE等四大模型对比与工业部署

Python声纹识别实战:EcapaTdnn/ResNetSE等四大模型对比与工业部署

简介:本资源是一套基于PaddlePaddle实现的声纹识别系统完整工程,面向人工智能方向的学习者、语音算法初学者及高校课程设计实践者,聚焦于说话人身份验证这一典型生物特征识别任务。项目集成EcapaTdnn、ResNetSE、ERes2Net、CAM等前沿模型&…

2026/10/13 16:37:09 阅读更多 →
Rust性能优化五技巧:数据结构、内存分配与缓存友好

Rust性能优化五技巧:数据结构、内存分配与缓存友好

Rust 的性能优化,说起来很有意思。大家选 Rust 多半是冲着性能来的,但真正把程序写出来之后,你会发现“能跑”和“跑得快”之间还有很长一段路。我早期做 Rust 项目时也走过弯路,一度以为堆一些 unsafe 代码、换更高级的算法就是优…

2026/10/13 16:37:09 阅读更多 →
开源大模型本地部署四件套:环境配置、私有部署、LoRA微调与LangChain接入

开源大模型本地部署四件套:环境配置、私有部署、LoRA微调与LangChain接入

简介:本资源是一套面向AI工程师与大模型应用开发者的开源大模型全栈实践工具包,聚焦环境配置、私有化部署、LoRA微调及LangChain集成四大核心环节,助力开发者快速落地本地化大模型应用。压缩包共79个文件,涵盖45个Python脚本&…

2026/10/13 16:37:09 阅读更多 →
实习和校招到底在选什么?从简历到面试的完整求职指南

实习和校招到底在选什么?从简历到面试的完整求职指南

1. 实习和校招到底在选什么很多同学第一次接触实习和校招的时候,脑子里冒出来的第一个问题往往是“我该投哪家”“简历怎么写”“面试问什么”。这些问题当然重要,但如果只盯着这些操作层面的东西,很容易陷入一种“做了很多准备却始终不得要领…

2026/10/13 16:36:05 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →