技术笔记技术笔记
2026-06-13

Shell脚本-MySQL数据库自动备份

#### 前提 确认已安装 `mysqldump`(MySQL 自带,一般都有) 提前准备:MySQL 账号、密码、数据库名 备份目录统一存放,示例路径:`/data/mysql_backup` #### 创建备份目录 ```bash mkdir -p /data/mysql_backup ``` #### 新建文件 `backup_mysql.sh` ```bash vim /data/backup_mysql.sh ``` #### 修改代码 ```bash #!/bin/bash # ==================== 手动修改以下配置 ==================== # MySQL 账号 DB_USER="账号" # MySQL 密码 DB_PWD="数据库密码" # 要备份的数据库名,多个库空格分隔 DB_NAME="test_db blog_db" # 备份文件存放目录 BACKUP_DIR="/data/mysql_backup" # 保留最近 7 天备份,自动删除旧文件 RETENTION_DAYS=7 # =========================================================== # 获取当前日期时间作为文件名 DATE=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="${BACKUP_DIR}/db_backup_${DATE}.sql.gz" # 执行备份 + 压缩 # --single-transaction:InnoDB 引擎热备份,不用停库、不锁表 mysqldump -u${DB_USER} -p${DB_PWD} --databases ${DB_NAME} \ --default-character-set=utf8mb4 --single-transaction --quick | gzip > ${BACKUP_FILE} # 判断备份是否成功 if [ $? -eq 0 ]; then echo "[$DATE] 数据库备份成功: ${BACKUP_FILE}" else echo "[$DATE] 数据库备份失败!" fi # 删除 N 天前的旧备份 # find -mtime +7:自动清理 7 天前备份,避免磁盘爆满 find ${BACKUP_DIR} -name "db_backup_*.sql.gz" -type f -mtime +${RETENTION_DAYS} -delete ``` > 遇到的坑:手动执行脚本文件可以生效,但是定时执行没有效果 `cron` 执行时的 `PATH` 通常很精简(只有 `/usr/bin:/bin`),一些命令可能无法执行,比如 `date`,`mysqldump`,`find`这些系统命令 解决办法:先在脚本文件中加 `source /.bashrc` 先加载一下环境,最好把 `find`,`date` 等一些系统命令换成绝对路径,执行 `which find data`,大概输出`/usr/bin/find`​ `/usr/bin/date`,然后把代码中用到的系统命令,例如 `find`,`date` 替换成 `/usr/bin/find` `/usr/bin/date` 这种绝对路径 ```bash #!/bin/bash source ~/.bashrc # 其他代码 ``` #### 添加执行权限 ```bash chmod +x /data/backup_mysql.sh ``` #### 手动测试执行(先跑一遍看是否报错) ```bash /data/backup_mysql.sh # 正常会在 /data/mysql_backup 生成 .sql.gz 压缩备份文件 ``` #### 设置定时任务(Crontab 自动执行)**每周一凌晨 2 点自动备份** ```bash # 编辑定时任务 crontab -e # 追加一行 0 2 * * 1 /data/backup_mysql.sh >> /data/mysql_backup/backup_log.txt 2>&1 # >> 日志文件:把运行日志记录下来,方便排查错误 # 查看当前定时任务 crontab -l # 常用时间格式参考(按需改) # 每 6 小时备份一次:0 */6 * * * # 每天中午 12 点:0 12 * * * # 每周一凌晨 2 点:0 2 * * 1 ``` #### 如何恢复备份(关键时刻用) ```bash # 解压备份文件 cd /data/mysql_backup gzip -d db_backup_20260612_020000.sql.gz # 导入恢复数据库 mysql -u账号 -p你的密码 < db_backup_20260612_020000.sql ``` #### 安全优化建议(云服务器必做) 不要把密码明文写脚本里(进阶安全) 编辑 MySQL 客户端配置,避免密码暴露: ```bash vim ~/.my.cnf ``` 写入 ```bash [mysqldump] user=账号 password=密码 ``` 权限收紧: ```bash chmod 600 ~/.my.cnf ``` 之后脚本里可以删掉 `-u${DB_USER} -p${DB_PASS}`,直接简写: ```bash mysqldump --databases ${DB_NAME} --single-transaction --quick | gzip > ${BACKUP_FILE} ```

标签Shell
标签Linux
技术笔记技术笔记
2026-06-10

Github Actions 使用

提交到 Github 平台的代码可以通过 Github Actions 进行代码的持续集成和持续交付(CI/CD),可以自动执行生成、测试和部署,避免每次都要手动的去更新代码,然后重新部署。 #### 1. 在项目根目录创建一个`.github` 目录,然后在目录中创建 `workflows` 目录 #### 2. 在 workflows 目录下创建以.yml 结尾的文件,名字随意 #### 3. 按自己的需求编辑 yml 文件,如下: ```yml # 名字按自己的需求随意 name: "Test" # 触发方式 on: # 代码提交时触发(可以指定分支) push: branches: - main - dev # 提交PR时触发 pull_request: # 提交issue时触发 issues: # 定时触发 schedule: # 工作流程 jobs: test1: # 说明要在Ubuntu环境中运行 run-on: ubuntu-latest # 运行步骤 steps: # 使用GitHub市场中已经存在的工作流 - uses: actions/setup-node@v4 with: node-version: 20 cache: 'npm' - name: 安装依赖 run: npm ci - name: 运行代码检查 run: npm run lint - name: 运行测试 run: npm test ``` 更详细的教程查看官网:[GithubActions](https://docs.github.com/en/actions/get-started/quickstart) 下面示例,使用 GitHub 自动连接远程服务器然后更新代码,重新部署 ```yml name: Deploy With Github Action on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: SSH连接服务器 uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.SERVER_HOST }} # 云服务器域名或IP username: ${{ secrets.SERVER_USER }} # SSH用户名 key: ${{ secrets.SSH_PRIVATE_KEY }} # ssh私钥内容 password: ${{ secrets.SERVER_PWD }} # ssh密码(如果使用密码登录) port: ${{ secrets.SERVER_PORT }} # ssh端口号 script: | cd app ./update.sh ``` 如果想通过 GitHub 远程连接自己的数据库,那么需要提供服务器的登录信息,登录信息最好不要直接写在文件中,可以在 GitHub 仓库的 `Settings` → `Secrets and variables` → `Actions` 中添加 例如添加以下键值对: `SERVER_HOST`:云服务器 IP 或域名 `SERVER_USER`:SSH 登录用户名(如 `root`、`ubuntu`) `SERVER_PASSWORD`:SSH 登录密码(可选,推荐使用 SSH 私钥,更安全) `SSH_PRIVATE_KEY`:SSH 私钥(内容,通常以 `-----BEGIN OPENSSH PRIVATE KEY-----` 开头) `SERVER_PORT`:SSH 端口(默认 22) #### 4. 遇到的问题 我在服务器上写了一个更新前后端项目代码并重新运行的 shell 脚本,运行需要用到 pm2 和 npm 我通过 GitHub Actions 连接服务器后直接运行部署脚本,发现有报错,提示 pm2 和 npm 不存在 排查发现 GitHub Actions 通过 SSH 登录后执行脚本的环境,和平时手动 SSH 登录服务器的环境不一样 GitHub Action 的 ssh-action 默认执行的是:`/bin/sh`或者非交互式 shell 不会加载:`.bashrc`​`.profile`​`.zshrc` 这些环境文件 所以 PATH 中没有:npm,pm2 等命令 导致:`npm: command not found`​`pm2: command not found` 然后我就想直接在 GitHub Actions 脚本命令中执行`source ./.bashrc`文件不就能加载环境变量了吗? 试了一下还是不行,`.bashrc`这个文件中都有防备,如果检测到非交互式,不会做任何事 ```bash # If not running interactively, don't do anything case $- in *i*) ;; *) return;; ``` 解决方法:在服务器上执行`witch pm2`,输出类似这种路径`/home/ubuntu/.nvm/versions/node/v22.18.0/bin` 复制,然后在我的服务器上的部署脚本里加上下面的代码, 把 Node.js 的安装目录追加到当前 Shell 的环境变量 PATH 中 ,这样就能在当前 shell 环境中使用 pm2 和 npm 了 `exportPATH=$PATH:/home/ubuntu/.nvm/versions/node/v22.18.0/bin`

标签Github
生活随记生活随记
2026-06-04

听赵雷,不倒霉

![.jpg](https://yzhthinking.top/files/fb66daab519544a6b970bf009ef7cfe9.jpg) > ***——程艾影***​ > > *一路望 跌跌撞 午夜流星何去何往* > > *路海长 青夜旷 越过群山追斜阳* > > *拨开面纱回望故乡 只见潮湿的月亮* > > *雨水冲不掉常德路上爬满蛛网的门窗* > > *梦里回到他的身旁 蜜语中风不再凉* > > *永远都像初次见你那样 使我心荡漾* > > *没有奇迹 没有惊喜 尘埃里花不会哭泣* > > *没有质疑 没有道理 褶皱的信乘飞雨* --- ![.jpg](https://yzhthinking.top/files/dca042cd929a4fc1b073cecd965256c0.jpg) > ***——我记得***​ > > *我记得这里是片树林 后面有个山坡* > > *山坡上的枣树每当秋天到来* > > *我们把枣装满口袋* > > *我记得除了朋友我还 做过你的叔父* > > *你总喜欢跟在我的屁股后面* > > *只是为了那几个铜钱* > > *我记得我们曾是恋人 后来战争爆发* > > *你上战场后就再也没有回来* > > *直到收不到你的信* > > *我们总这样重复分离 却要重新开始* > > *相互送别对方说着来世再见* > > *再次失忆着相聚* > > *在路上我遇到了一位故去多年的人* > > *她是如此年轻扎着过肩马尾* > > *露出和你一样的笑* > > *她和我讲了很多关于你成长的故事* > > *在星空另一端思念从未停止* > > *如同墓碑上的名字* > > *不要哭我最亲爱的人 我最好的玩伴* > > *时空是个圆圈直行或是转弯* > > *我们最终都会相见* > > *在城池的某个拐角处 在夕阳西下时* > > *在万家灯火的某一扇窗纱里* > > *人们失忆着相聚* --- ![.jpg](https://yzhthinking.top/files/36ee3f2caade461e8cd09a1e016da5ba.jpg) > ***——朵*** > > *最美的是月亮 岁月无法改变她的模样* > > *雨后的花儿卸去了妆 还我一张真实的脸庞* > > *我爱这世间美貌的女子* > > *可是她们却不是我的* > > *我多么想你能变成我永不凋零的花朵* > > *但时间不会让你永远的停泊* > > *所以我爱这世间清纯的女子* > > *可是她们的话分不清真假* > > *我多么想你能摆脱这世间给予的浮夸* > > *就像我母亲年轻时那样的无华* --- ![.png](https://yzhthinking.top/files/3aa5dd4e9b8741828b3979b2713dfb5b.png) > ***——画***​ > > *画一群鸟儿围着我* > > *再画上绿岭和青坡* > > *画上宁静与祥和* > > *雨点儿在稻田上飘落* > > *画上有你能用手触到的彩虹* > > *画中有我决定不灭的星空* > > *画上弯曲无尽平坦的小路* > > *尽头的人家梦已入* > > *画上母亲安详的姿势* > > *还有橡皮能擦去的争执* > > *画上四季都不愁的粮食* > > *悠闲的人从没心事* > > *我没有擦去争吵的橡皮* > > *只有一支画着孤独的笔* > > *那夜空的月也不再亮* > > *只有个忧郁的孩子在唱*

技术笔记技术笔记
2026-06-01

服务器安全加固

##### 创建普通用户,设置复杂密码,授予 sudo 权限 ```bash sudo useradd -m 用户名 sudo passwd 用户名 sudo usermod -aG sudo 用户名 groups 用户名 # 查看用户名所属的用户组 ``` ##### 修改 ssh 配置文件,修改 ssh 默认端口,禁止 root 用户登录 ```bash vim /etc/ssh/sshd_config 找到 Port 22 修改成 Port 其他数(10000-65535 之间) 找到 PermitRootLogin yes 改成 PermitRootLogin no,禁止 root 用户登录 保存退出,重新加载配置 systemctl restart ssh ``` ##### 开启防火墙,只开放用到的端口 ```bash # 查看防火墙状态 systemctl status ufw # 开启防火墙 systemctl start ufw # 开放必要端口 sudo ufw allow 80/tcpsudo ufw allow 443/tcp # 设置开机自启 systemctl enable ufw # 查看已开放端口 ufw status ``` ##### 密码要设置复杂一点,不要用 admin,123456 这种,很容易被暴力破解,要定期修改密码 ##### 安装 fail2ban,拦截暴力破解,监控服务器登录记录,自动拉黑多次密码错误的 IP ```bash sudo apt install fail2ban -y # 启动 fail2ban 并设置开机自启 systemctl start fail2ban && systemctl enable fail2ban # 查看 fail2ban 状态,active 即启动成功 systemctl status fail2ban ``` ##### 关闭无用服务,定期更新系统 ```bash # 查看正在运行的服务 systemctl list-unit-files --type=service --state=enabled # 关闭并禁用无用的服务 systemctl stop 服务名 && systemctl disable 服务名 # 更新系统和软件 sudo apt update && sudo apt upgrade -y ```

标签Linux
技术笔记技术笔记
2026-06-01

Nginx配置项

```bash # nginx是以www-data这个用户的身份去运行的 user www-data; # nginx以多少个工作进程启动,auto会根据cpu核心数自动设置 worker_processes auto; # 用于记录nginx主进程的PID,便于进程管理 pid /run/nginx.pid; # nginx错误日志存放地址 error_log /var/log/nginx/error.log; # 加载nginx已启用模块的配置 include /etc/nginx/modules-enabled/*.conf; events { # 每个worker进程最大可连接数,总并发上限约等于worker_processes x worker_connections worker_connections 768; # 开启后一个worker一次性接收所有新连接,高并发时提升性能,但是可能增加单个请求的延迟 # multi_accept on ; } http { ## # Basic Settings ## # 提高文件传输效率 sendfile on; # 与sendfile配合,尽量攒满TCP包再发送,减少小包数量,提高大文件传输效率 tcp_nopush on; # MIME类型哈希表大小 types_hash_max_size 2048; # 安全配置,关闭http响应头显示nginx版本号 server_tokens off; # 隐藏Nginx服务器名称 (安全强化,推荐) server_name_in_redirect off; # 客户端请求头缓冲区大小(大并发必调) client_header_buffer_size 2k; # 客户端请求体大小限制(上传文件必配!) client_max_body_size 10m; # 默认 1m,上传图片/文件会 413 错误 # 长连接超时时间(高并发必配) keepalive_timeout 65; # 单个长连接最多处理多少请求(防攻击) keepalive_requests 100; # 客户端发送请求体超时时间 client_body_timeout 10; # 客户端发送请求头超时时间 client_header_timeout 10; # 发送响应到客户端超时时间 send_timeout 10; # 用于存储server_name的哈希表大小,当server_name很长或很多时可能报错 # server_names_hash_bucket_size 64; # 默认开启,重定向时会带上server_name,关闭后用请求头中的Host决定重定向目标 # server_name_in_redirect off; # 引入MIME类型映射表,如 .html-&gt;text/html,让浏览器正确解析文件类型 include /etc/nginx/mime.types; # 默认MIME类型,当文件扩展名在mime.types中找不到时,以此类型返回,octet-stream 未匹配MIME类型时按二进制 流返回,浏览器通常会下载处理 default_type application/octet-stream; ## # SSL Settings ## # 允许的TLS版本 建议使用TLS1.2 TLSv1.3 (TLSv1 TLSv1.1 已淘汰多年) ssl_protocols TLSv1.2 TLSv1.3; # 优先使用服务端指定的加密套件顺序,而非客户端(TLS1.2及以下配置生效,TLS1.3不受此配置影响) ssl_prefer_server_ciphers on; ## # Logging Settings ## # 自定义日志格式:包含真实IP、请求耗时、后端响应耗时(排查问题神器) log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '请求耗时:$request_time s 后端响应耗时:$upstream_response_time s'; # 访问日志路径,记录请求的IP,时间,URL,状态码,UA等,用于流量分析和问题排查 access_log /var/log/nginx/access.log; ## # Gzip Settings ## # 开启gzip压缩,文本类资源压缩后体积通常减少60%~80%,显著提升加载速度 gzip on; # 开启后根据客户端是否支持gzip返回不同的Vary:Accept-Encoding头,配合CDN缓存更友好 # gzip_vary on; # 对代理请求也压缩。设为 any 会压缩所有代理请求,但某些老旧客户端可能不支持。 # gzip_proxied any; # 压缩级别 1-9,6 是压缩率和 CPU 消耗的平衡点。级别越高压缩越小但 CPU 越高 # gzip_comp_level 6; # 分配 16 个 8KB 缓冲区用于压缩,总共 128KB # gzip_buffers 16 8k; # 只对 HTTP/1.1 及以上启用压缩(HTTP/1.0 默认不压缩) # gzip_http_version 1.1; # 指定哪些 MIME 类型需要压缩。默认已包含 text/html,通常无需手动设置 # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; ## # 安全响应头配置(防止 XSS、点击劫持,企业安全必备) ## add_header X-Frame-Options SAMEORIGIN always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options nosniff always; ## # 反向代理通用配置(对接 Java/Go/Node 后端必用) ## proxy_set_header Host $host; # 传递用户真实 IP 给后端服务器 proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 代理超时时间(防止慢请求拖垮 Nginx) proxy_connect_timeout 10s; proxy_send_timeout 30s; proxy_read_timeout 30s; ## # Virtual Host Configs ## # 加载 conf.d/ 目录下所有 .conf 文件。通常放通用配置(如反向代理、全局规则) include /etc/nginx/conf.d/*.conf; # 加载已启用的站点配置。这是 nginx 推荐的站点管理方式:sites-available/ 放所有站点,sites-enabled/ 用软链接启用需要的站点 include /etc/nginx/sites-enabled/*; } ```

标签Nginx
标签Linux