简介:《DeepSeek 部署详细方式》是一份面向具备一定 Linux 或 Windows Server 运维基础、希望独立完成平台搭建与配置的开发者和技术人员的操作文档,重点解决从环境准备到服务上线过程中步骤分散、配置项繁多的问题。内容按准备工作、安装步骤、后续配置与优化三部分组织,涵盖服务器硬件与网络要求、操作系统与数据库选型、Python 环境、域名及 SSL 证书准备,并逐步说明数据库连接配置、依赖包安装、数据库初始化、Web 服务器反向代理设置、服务启动与访问测试等环节;后续部分还涉及用户权限管理、数据导入与索引配置、并发与缓存调优、负载均衡、安全加固、监控日志等运维要点。压缩包内共 1 个 doc 文件,约 35KB,以纯文档形式集中呈现部署清单与配置说明,便于按章节查阅和对照操作。目前已有 1541 人学习,适合用作部署前的流程梳理与配置核对参考,也可帮助读者建立从环境准备到上线运维的整体认识。
1. 从一台干净服务器说起:DeepSeek 部署真正卡人的三个位置
拿到一台刚重装好的服务器,多数人第一反应是 clone 代码、pip install,然后被一串红色报错按在地上。DeepSeek 这类智能数据搜索与分析平台的部署,卡人的位置其实很固定:数据库连接串的字符集和权限、Python 依赖的编译环境、Nginx 与应用之间的超时与转发头。这三处任意一个参数写错,浏览器里看到的都是同一张白屏或者 502,看着像玄学,实际每一步都有明确成因。这篇面向的是手上已经有一台 Linux 机器、准备把平台真正跑起来的人,从选型、装包、建库、托管服务一路写到上线后的索引与备份。只想在本地看界面的话,直接翻到最后一章的验收清单更快。
2. 环境选型与前置准备:CPU、内存、数据库三处必须先定死
部署失败里有一大半不是装的时候出错,而是准备阶段埋的雷。硬件估小了,索引建到一半内存被打爆;数据库版本选错,初始化脚本的 DDL 直接语法报错;时区和文件句柄数没改,跑两天之后日志时间对不上、连接数上不去。这一章按“先定死、再动手”的顺序,把选型理由和具体命令都摆出来,照着改参数就能用。
2.1 硬件与操作系统的选型逻辑
搜索分析类平台的负载有明显阶段特征:建索引阶段吃单核性能和磁盘顺序写,查询阶段吃内存和并发连接,数据导入阶段吃网络带宽。所以不能只看“几核几 G”,要按你实际的数据量和使用人数来估。
| 使用规模 | CPU | 内存 | 磁盘 | 带宽 | 说明 |
|---|---|---|---|---|---|
| 个人验证、内部试用 | 4 核 | 8 GB | 100 GB SSD | 5 Mbps | 几十万条文档量级够用 |
| 小团队日常检索 | 8 核 | 16–32 GB | 300 GB SSD | 20 Mbps | 十余人并发,缓存给足 |
| 部门级、以检索为主 | 16 核以上 | 64 GB 起 | NVMe,容量按原始数据 2–3 倍估 | 100 Mbps | 索引与数据分盘存放 |
内存的估算方法很朴素:索引文件加上热点数据缓存,粗略按原始文本体积的 1.5 倍预留,剩下的留给系统和数据库。机械盘不要考虑,随机读延迟会把检索响应拖到秒级,用户体感就是“这平台不好用”。带宽影响的主要是首次全量导入的耗时,不是查询速度,别在这上面过度投入。
操作系统优先 Linux,理由是进程托管有 systemd、权限模型清晰、Nginx 与日志轮转的生态成熟,出问题时有现成的排查路径。发行版选还在维护周期内的 LTS 版本,不要为了“新”去选刚发布的版本。Windows Server 技术上能跑,但 Gunicorn 不原生支持,需要换 waitress 之类的方案,运维脚本、开机自启、日志切割全都要重写,团队里没有熟悉 Windows 运维的人就不要选它。
系统层面的三项前置调整,很多人会漏:
# 统一时区,避免日志时间与应用内时间对不上,令牌校验也依赖它 sudo timedatectl set-timezone UTC timedatectl status # 时间同步,容器和云主机漂移很常见 sudo systemctl enable --now systemd-timesyncd # 提高文件句柄上限,搜索类服务并发打开的文件远多于普通 Web 应用 sudo tee /etc/security/limits.d/99-deepseek.conf <<'EOF' deepseek soft nofile 65535 deepseek hard nofile 65535 EOF # 内核层面的连接队列,高并发下默认值偏小 sudo tee /etc/sysctl.d/99-deepseek.conf <<'EOF' net.core.somaxconn = 1024 net.ipv4.tcp_max_syn_backlog = 2048 vm.swappiness = 10 EOF sudo sysctl --system时区按团队习惯统一即可,关键是应用、数据库、Nginx 三处一致,否则排查问题时时间线会对不上,这是血泪经验。nofile那条要确认生效,su - deepseek -c 'ulimit -n'输出 65535 才算数,只在当前 shell 里改是没用的。vm.swappiness调低是让系统尽量别把索引缓存换到 swap,一旦发生换页,检索延迟会突然抖一下,很难复现。
2.2 数据库与 Python 运行时的落地配置
数据库选型的判断依据只有一个:看安装包里的初始化脚本用的是什么方言。脚本里出现AUTO_INCREMENT、ENGINE=InnoDB就是 MySQL 系,出现SERIAL、CREATE TYPE就是 PostgreSQL 系。不要凭喜好硬换,DDL 不兼容的报错会在初始化那一步集中爆发,改起来非常费时间。
确定 MySQL 之后,建库建用户这一步要一次做对:
-- 字符集必须是 utf8mb4,utf8 存不下四字节字符,中文检索会出现截断 CREATE DATABASE deepseek DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci; -- 只允许本机连接,应用和数据库同机部署时不要开 % CREATE USER 'ds_user'@'127.0.0.1' IDENTIFIED BY '替换成十六位以上的强密码'; -- 只给这个库的权限,不给全局权限 GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, REFERENCES ON deepseek.* TO 'ds_user'@'127.0.0.1'; FLUSH PRIVILEGES;字符集这一项踩坑率极高:建库时用了默认的 latin1 或者 utf8,导入中文数据不报错,查询时却出现乱码或者干脆搜不到,事后改字符集要重建表。127.0.0.1而不是%,是因为应用和数据库同机,没有理由让数据库端口对外可见。权限按需给,初始化脚本需要CREATE和ALTER,跑完之后可以再收一次。
数据库服务端的几个参数,直接影响后续性能:
# /etc/mysql/conf.d/deepseek.cnf [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_general_ci max_connections = 300 innodb_buffer_pool_size = 4G innodb_flush_log_at_trx_commit = 2 slow_query_log = 1 long_query_time = 2innodb_buffer_pool_size一般给物理内存的 50%–60%,给太少会导致频繁刷盘。innodb_flush_log_at_trx_commit = 2是把每次事务刷盘改成每秒刷盘,写入性能提升明显,代价是断电可能丢最后一秒的事务;如果这份数据不能丢,就保持默认的 1。slow_query_log建议一开始就开,上线后第一批性能问题基本都能从慢查询日志里找到线索。
Python 运行时用虚拟环境隔离,不要往系统 Python 里装依赖:
# 编译型依赖需要的系统包,缺了会在 pip 阶段报 gcc 错误 sudo apt install -y python3 python3-venv python3-dev build-essential \ libmysqlclient-dev pkg-config # 确认版本,3.8 以上基本都能跑,具体下限看安装包说明 python3 -Vpython3-dev和build-essential是给需要现场编译的包准备的,纯 wheel 分发的包用不上,但少装了的后果是 pip 报command 'gcc' failed,新手容易在这里卡半天。libmysqlclient-dev对应 MySQL 驱动,用 PostgreSQL 就换成libpq-dev。
2.3 域名与证书:别等上线才想起 HTTPS
平台带登录态,明文 HTTP 传密码是绝对不能上线的。准备工作里把域名和证书一次做完,比事后补要省事得多。
先在域名服务商处加一条 A 记录指向服务器公网 IP,用dig确认解析生效再往下走,解析没生效时申请证书会失败,报错信息还很有迷惑性。
# 确认解析已经指向本机 dig +short search.example.com # 安装 certbot 及其 Nginx 插件 sudo apt install -y certbot python3-certbot-nginx # 自动改写 Nginx 配置并加上 80 到 443 的跳转 sudo certbot --nginx -d search.example.com --redirect # 演练续期,确认定时任务能跑通 sudo certbot renew --dry-run--redirect会自动插入 301 跳转,省去手写。--dry-run这一步不要省,证书三个月到期,续期失败而没人发现的话,某天早上整个平台会直接打不开。certbot 安装时会自带 systemd timer,用systemctl list-timers | grep certbot确认一下。防火墙只需要放行 80 和 443,应用端口 8000 和应用到数据库的 3306 都不应该对外。
3. 安装包落地与数据库初始化:从解压到第一张表
装包这一步的动作不多,但对顺序和权限的要求比较严。用 root 跑应用、把代码放在/root下、虚拟环境和系统 Python 混用,这三件事在后期都会变成麻烦。下面按“建用户 → 放代码 → 装依赖 → 写配置 → 初始化”的顺序走一遍。
3.1 目录规划与专用用户
先建一个不能登录系统的服务账号,把代码、虚拟环境、日志、索引数据分目录放:
# 建服务账号,-r 表示系统用户,不创建家目录登录 shell sudo useradd -r -s /usr/sbin/nologin deepseek # 目录规划:代码、虚拟环境、日志、索引数据、备份各占一个 sudo mkdir -p /opt/deepseek/{app,venv,logs,data,backup} # 归属给服务账号,后续所有操作都用它执行 sudo chown -R deepseek:deepseek /opt/deepseek sudo chmod 750 /opt/deepseek索引数据单独放data目录,是因为它的增长速度和访问模式和代码完全不同,有条件的话单独挂一块盘。日志单独放是为了配 logrotate 时不用去动应用目录。
把安装包上传到/opt/deepseek/app再解压:
sudo -u deepseek bash cd /opt/deepseek/app # 安装包从官方渠道获取后上传,这里用占位文件名 tar -xzf deepseek-release.tar.gz --strip-components=1 ls -la--strip-components=1用来剥掉压缩包自带的那层顶层目录,避免出现app/app/...这种嵌套。解压后确认能看到requirements.txt、wsgi.py(或等价的入口文件)和配置样例,这三个是后续步骤的锚点。
3.2 依赖安装与虚拟环境隔离
# 切到服务账号,后续命令都在这个身份下执行 sudo -u deepseek -i cd /opt/deepseek python3 -m venv venv source venv/bin/activate # 升级打包工具,老版本 pip 解析依赖会很慢甚至失败 pip install --upgrade pip wheel setuptools # 按清单安装,加上超时和重试,网络不稳时不会整批失败 pip install -r app/requirements.txt --timeout 60 --retries 3python3 -m venv建出来的环境是独立的,装多少包都不影响系统。--timeout和--retries在内网或者跨境网络环境下很实用,默认超时偏短,一个大包下到一半断掉会重头再来。
如果目标机器不能出网,在能出网的机器上先下载再传过去:
# 在有网机器上执行,把依赖包下载成 whl 文件 pip download -r requirements.txt -d ./wheels --only-binary=:all: # 目标机器上从本地目录安装,不走网络 pip install --no-index --find-links=./wheels -r requirements.txt--only-binary=:all:强制只下 wheel,避免把源码包带过去还要现场编译。有些包没有对应平台的 wheel,这时会报错,去掉这个参数单独处理那一个即可。
装完做一次自检,确认关键依赖能被导入:
python -c "import flask, sqlalchemy; print('deps ok')" pip checkpip check会检查依赖版本冲突,输出No broken requirements found才算干净。
3.3 配置文件里的数据库连接参数
配置文件的位置和格式各家不一样,常见的是config.json或settings.py。以 JSON 为例,需要改的通常是这几项:
{ "database": { "type": "mysql", "host": "127.0.0.1", "port": 3306, "name": "deepseek", "user": "ds_user", "password": "从环境变量 DS_DB_PASSWORD 读取", "pool_size": 10, "pool_recycle": 3600 }, "server": { "host": "127.0.0.1", "port": 8000, "workers": 4, "timeout": 120 }, "search": { "index_path": "/opt/deepseek/data/index", "cache_size": 512 } }| 参数 | 建议值 | 说明 |
|---|---|---|
host | 127.0.0.1 | 应用与数据库同机,不要填公网地址 |
pool_size | 10–20 | 连接池大小,应大于等于 worker 数乘 2 |
pool_recycle | 3600 | 连接回收秒数,避免被数据库端主动断开 |
server.host | 127.0.0.1 | 只监听本机,由 Nginx 对外 |
server.workers | CPU 核数 | 与 Gunicorn 的-w保持一致 |
server.timeout | 120 | 检索慢查询需要更长超时 |
cache_size | 按内存给 | 单位以安装包说明为准,别超过物理内存一半 |
密码不要明文写在配置里,用环境变量注入,配置里只留变量名。文件权限也要收:
chmod 600 /opt/deepseek/app/config.json # 密码写进环境变量文件,systemd 会读它 cat > /opt/deepseek/app/.env <<'EOF' DS_DB_PASSWORD=替换成真实密码 EOF chmod 600 /opt/deepseek/app/.envpool_recycle这一项经常被忽略,MySQL 默认wait_timeout是 8 小时,连接池里的空闲连接被服务端单方面断掉之后,应用拿到的是失效连接,表现就是隔一段时间出现一次莫名其妙的查询失败。
3.4 初始化脚本执行与结果校验
初始化只跑一次,跑之前确认数据库是空的,跑之后立刻校验表结构:
source /opt/deepseek/venv/bin/activate cd /opt/deepseek/app # 具体子命令以安装包内的脚本为准,常见形式如下 python manage.py db init python manage.py db upgrade执行时把输出重定向一份到日志,失败时好回溯:
python manage.py db init 2>&1 | tee /opt/deepseek/logs/init_$(date +%F).log校验不能只看“没报错”,要进数据库确认:
USE deepseek; SHOW TABLES; SELECT COUNT(*) AS table_count FROM information_schema.tables WHERE table_schema = 'deepseek'; -- 抽查一张核心表的字符集,确认是 utf8mb4 SELECT table_name, table_collation FROM information_schema.tables WHERE table_schema = 'deepseek' AND table_name = 'documents';表数量应该和安装包文档里列出的对得上,字符集全部是utf8mb4。如果出现utf8mb3或者latin1,说明建库时字符集没设对,这时候数据还没导入,删库重来成本最低;等导完数据再改,就要写迁移脚本了。
4. Web 服务托管与反向代理:Gunicorn、Nginx、systemd 三件套
应用能本地跑通,距离“能给同事用”还差三步:换成生产级 WSGI 服务器、用 Nginx 挡在前面、用 systemd 托管保证崩溃自启。这三件事分开看都简单,配在一起时超时、转发头、启动顺序经常对不上,表现出来就是间歇性 502。
4.1 为什么不能直接用开发服务器跑
安装包里通常带一个python app.py或者flask run的启动方式,那是开发用的:单进程、无并发、崩溃不重启、也没有请求超时保护。搜索类请求里有大量等待 IO 的时间,单进程会把并发直接卡死。
生产环境用 Gunicorn,worker 类型选gthread:
# 手工验证一次,确认能起来再交给 systemd /opt/deepseek/venv/bin/gunicorn \ -w 4 \ -k gthread \ --threads 4 \ -b 127.0.0.1:8000 \ --timeout 120 \ --graceful-timeout 30 \ --access-logfile /opt/deepseek/logs/access.log \ --error-logfile /opt/deepseek/logs/error.log \ wsgi:app-w 4是进程数,经验值是 CPU 核数,多了反而因为上下文切换变慢。-k gthread --threads 4用线程模型,适合检索这种等待多的场景,总并发大致是 4×4。--timeout 120是单个请求的上限,超过就被杀掉重启,这个值要和 Nginx 的proxy_read_timeout对齐,Nginx 那边要略大一点,否则会出现应用还在算、Nginx 已经返回 504 的情况。wsgi:app是入口,以安装包里的实际文件名为准。
4.2 Nginx 反向代理与静态资源配置
Nginx 负责三件事:终止 TLS、转发请求、直接吐静态文件。静态文件交给 Nginx 能省掉一大截应用层的开销。
# /etc/nginx/conf.d/deepseek.conf upstream deepseek_app { server 127.0.0.1:8000; keepalive 32; } server { listen 80; server_name search.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name search.example.com; ssl_certificate /etc/letsencrypt/live/search.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/search.example.com/privkey.pem; # 数据导入走的是同一个域名,上传限制要给足 client_max_body_size 200m; location /static/ { alias /opt/deepseek/app/static/; expires 7d; access_log off; } location / { proxy_pass http://deepseek_app; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Connection ""; # 必须大于 Gunicorn 的 --timeout,否则应用还在算 Nginx 先放弃了 proxy_read_timeout 150s; proxy_connect_timeout 10s; } }X-Forwarded-Proto少了这一行,应用生成的重定向链接会是http://,登录后跳转直接失败。proxy_http_version 1.1加Connection ""是为了让 upstream 复用长连接,默认的 1.0 每条请求都新建连接,QPS 高的时候 TIME_WAIT 会堆起来。client_max_body_size默认只有 1M,导入数据时必然 413,这一条在避坑章还会提到。
改完先测语法再 reload,不要直接 restart:
sudo nginx -t sudo systemctl reload nginx4.3 systemd 托管与开机自启
手工启的进程一关终端就没了,必须交给 systemd:
# /etc/systemd/system/deepseek.service [Unit] Description=DeepSeek Search Service After=network.target mysql.service Wants=mysql.service [Service] Type=simple User=deepseek Group=deepseek WorkingDirectory=/opt/deepseek/app Environment="PATH=/opt/deepseek/venv/bin" EnvironmentFile=-/opt/deepseek/app/.env ExecStart=/opt/deepseek/venv/bin/gunicorn -c /opt/deepseek/app/gunicorn.conf.py wsgi:app Restart=always RestartSec=5 LimitNOFILE=65535 StandardOutput=append:/opt/deepseek/logs/stdout.log StandardError=append:/opt/deepseek/logs/stderr.log [Install] WantedBy=multi-user.targetAfter=mysql.service保证启动顺序,数据库没起来时应用会重试而不是直接崩。EnvironmentFile把密码从配置文件里解耦出来,注意前面有个-,表示文件不存在也不报错。Restart=always配合RestartSec=5是最后一道保险,进程因为内存溢出被杀掉时能自动拉起。LimitNOFILE要和前面 limits 里设的值一致,systemd 托管的进程不读/etc/security/limits.d。
启用并查看状态:
sudo systemctl daemon-reload sudo systemctl enable --now deepseek sudo systemctl status deepseek --no-pager4.4 启动后的五步验收
不要看到active (running)就以为成了,按下面五步逐层验证:
# 1. 端口是否在监听 ss -lntp | grep 8000 # 2. 应用本机自检 curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8000/health # 3. 经过 Nginx 的自检 curl -s -o /dev/null -w "%{http_code}\n" https://search.example.com/health # 4. 证书与跳转是否正常 curl -I http://search.example.com # 5. 日志里有没有 ERROR grep -c "ERROR" /opt/deepseek/logs/error.log第 1 步没输出,说明应用根本没起来,去看journalctl -u deepseek -n 100。第 2 步返回 200 而第 3 步不是,问题在 Nginx 配置或证书。第 4 步应该看到 301 到 https。第 5 步计数不为 0 也不一定是故障,但要逐条看。五步都过了,再让真实用户登录做一次检索,才算验收完成。
5. 部署避坑清单:五个把服务卡死的常见问题
下面五条是按“现象 → 原因 → 解决”整理的,都是部署现场反复出现的,出现频率从高到低排。
5.1 启动阶段:服务起不来
现象一:systemctl status显示 failed,日志里是Access denied for user 'ds_user'@'localhost'
原因通常是两处:一是配置文件里的密码和.env里的不一致,二是 MySQL 里建的用户 host 是127.0.0.1,但应用解析localhost时走了 socket 连接,匹配不上。解决方法是先手工验证凭据:
mysql -h 127.0.0.1 -P 3306 -u ds_user -p deepseek -e "SELECT 1;"这条能通而应用不通,就去检查配置文件里host是不是写成了localhost。把localhost统一改成127.0.0.1,强制走 TCP,行为最可控。
现象二:active (running)但ss -lntp看不到 8000 端口
进程活着但没监听,多半是入口文件路径写错,Gunicorn 在别的目录找不到wsgi:app,或者应用的server.host配置成了别的地址。看journalctl -u deepseek -n 200,里面会有Failed to find application object之类的明确报错。WorkingDirectory必须指向wsgi.py所在目录,ExecStart里的模块路径要和实际文件名一致。
5.2 访问阶段:能连上但打不开
现象三:浏览器 502 Bad Gateway
Nginx 连不上上游。按顺序查三处:curl 127.0.0.1:8000通不通;SELinux 或防火墙有没有拦住本机回环(一般不会);upstream 地址和端口是否和 Gunicorn 的-b一致。有一种隐蔽情况是 Gunicorn 启动了但 worker 全部因为导入错误退出,主进程还在,端口也占着,请求进来直接 502,这时候error.log里会有大段 traceback。
现象四:导入数据时 413 Request Entity Too Large
Nginx 的client_max_body_size默认 1M。改配置里的这个值并 reload 即可,同时确认应用层有没有自己的上传大小限制,两边要一起改,只改一边会出现“Nginx 放行了但应用拒绝”。
现象五:登录成功但页面跳回登录页,或者链接变成 http
原因是X-Forwarded-Proto没传给应用,应用以为自己跑在 HTTP 上,生成的 Cookie 没带 Secure 或者重定向到 http 地址又被跳回来,形成循环。检查 Nginx 配置里那行proxy_set_header X-Forwarded-Proto $scheme;是否在location /里,改完 reload。这类问题在浏览器里看 Network 面板的重定向链最直观。
5.3 运行阶段:越用越慢
现象六:检索响应从几百毫秒涨到几秒,重启后恢复
典型的连接池泄漏或缓存无上限增长。先看数据库侧的连接数:
SHOW STATUS LIKE 'Threads_connected'; SHOW PROCESSLIST;连接数持续上涨不回落,说明应用侧有连接没归还,检查pool_size是否配得过大、有没有在异常分支里漏了关闭。另一种情况是search.cache_size给得太大,把物理内存吃满触发 swap,表现就是整体变慢而不是某个接口慢,用free -h和vmstat 1看换页情况就能区分。
现象七:中文关键词搜不到结果,英文正常
字符集问题。按 3.4 节的 SQL 抽查表和字段的字符集,任何一处是utf8mb3或latin1都要改。已经导入数据的表用ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4转换,转换前必须备份,大表转换会锁表,安排在低峰期做。
6. 上线之后:索引、并发与备份的三个调优动作
平台跑起来只是开始,真正决定好不好用的是索引构建策略和备份是否可靠。索引这块,我的习惯是先把cache_size给到物理内存的 30% 左右观察一周,再按命中率往上加,一次加太多会挤掉数据库的 buffer pool,反而两头不讨好。批量导入时把单条写入改成按批提交,每批 500 到 1000 条,配合关闭自动提交,千万级数据导入能从几小时压到几十分钟,代价是失败时要整批重来,所以导入前先备份。
并发方面,workers不要超过 CPU 核数,线程数按“等待时间 / 计算时间”估,检索类场景 4 到 8 个线程比较稳。真正的瓶颈通常在数据库,把慢查询日志里出现频率最高的三条 SQL 加上合适索引,比调应用参数见效快得多。
备份做成最小闭环就三件事:数据库每天全量、索引目录每周打包、配置和.env每次变更后同步一份到异地。用一条 cron 覆盖前两项:
#!/usr/bin/env bash # /opt/deepseek/backup/backup.sh set -euo pipefail STAMP=$(date +%F) DEST=/opt/deepseek/backup # 数据库全量导出,--single-transaction 保证 InnoDB 表一致性快照 mysqldump -h 127.0.0.1 -u ds_user -p"${DS_DB_PASSWORD}" \ --single-transaction --routines --triggers \ deepseek | gzip > "${DEST}/db_${STAMP}.sql.gz" # 索引目录打包,排除临时文件 tar -czf "${DEST}/index_${STAMP}.tar.gz" \ --exclude='*.tmp' -C /opt/deepseek/data index # 只保留最近 14 天,避免磁盘被撑爆 find "${DEST}" -name "*.gz" -mtime +14 -delete--single-transaction让导出过程不锁表,线上可跑。脚本里读密码用环境变量,不要写死在文件里。最关键的其实不是备份,是恢复演练:每隔一段时间拿备份在测试机上真恢复一次,不演练的备份等于没有。从那以后我每次交付前都强制走一遍“导出一份、恢复一份、搜一条”的流程,这条习惯救过我不止一次。希望帮到你。
本文还有配套的精品资源,点击获取