opengauss教程FG021-openGauss增量备份与时间点恢复
目录大纲
Part01-基础概念与理论知识
1.1 增量备份概述
增量备份是指只备份自上次备份以来发生变化的数据,了解增量备份的概念和方法对于数据库的备份策略至关重要。风哥教程参考opengauss官方文档,增量备份具有以下特点:
- 节省存储空间:只备份变化的数据,减少备份文件大小
- 缩短备份时间:只备份变化的数据,减少备份时间
- 提高恢复速度:可以快速恢复到最近的备份点
- 依赖全量备份:增量备份需要基于全量备份进行
1.2 时间点恢复概述
时间点恢复是指将数据库恢复到指定的时间点,了解时间点恢复的概念和方法对于数据库的灾难恢复至关重要:
- 精确恢复:可以恢复到任意指定的时间点
- 数据保护:可以恢复因误操作导致的数据丢失
- 灵活恢复:可以根据需要选择恢复点
- 依赖WAL日志:时间点恢复需要WAL日志的支持
1.3 WAL日志与增量备份的关系
WAL(Write-Ahead Logging)日志是数据库的事务日志,与增量备份密切相关:
- WAL日志记录:记录所有数据库修改操作
- 增量备份基础:增量备份基于WAL日志进行
- 时间点恢复支持:WAL日志支持时间点恢复
- 数据一致性:确保数据的一致性和可靠性
风哥提示:WAL日志是增量备份和时间点恢复的基础,正确配置和管理WAL日志对于数据库的安全和可靠性至关重要。
Part02-生产环境规划与建议
2.1 增量备份规划
生产环境增量备份规划建议
- 备份策略:
- 全量备份:每周一次
- 增量备份:每天一次
- 差异备份:每两天一次
- 备份时间:
- 选择业务低峰期进行备份
- 避免在系统负载高时进行备份
- 备份存储:
- 使用异地存储
- 多副本存储
- 定期清理过期备份
- 备份验证:
- 定期验证备份的有效性
- 测试恢复过程
2.2 时间点恢复规划
生产环境的时间点恢复规划建议:
- 恢复策略:
- 制定详细的恢复计划
- 明确恢复步骤和责任人
- 定期演练恢复过程
- 恢复时间目标(RTO):
- 根据业务需求确定RTO
- 确保备份策略能够满足RTO要求
- 恢复点目标(RPO):
- 根据业务需求确定RPO
- 确保备份策略能够满足RPO要求
- 恢复测试:
- 定期进行恢复测试
- 验证恢复过程的有效性
风哥提示:
2.3 WAL日志管理
WAL日志管理建议:
- WAL日志配置:
- 启用WAL归档
- 设置合适的WAL段大小
- 配置WAL日志保留策略
- WAL日志存储:
- 使用高性能存储
- 考虑使用独立的存储设备
- 确保存储空间足够
- WAL日志监控:
- 监控WAL日志使用情况
- 及时清理过期的WAL日志
- 确保WAL日志的连续性
学习交流加群风哥微信: itpux-com
Part03-生产环境项目实施方案
3.1 配置WAL归档
# 配置WAL归档
[opengauss@fgedu.net.cn ~]$ vim /opengauss/fgdata/postgresql.conf
# 修改以下参数
wal_level = logical
archive_mode = on
archive_command = ‘cp %p /opengauss/backup/wal/%f’
archive_timeout = 60
# 创建WAL归档目录
[opengauss@fgedu.net.cn ~]$ mkdir -p /opengauss/backup/wal
[opengauss@fgedu.net.cn ~]$ chown -R opengauss:dbgrp /opengauss/backup
# 重启数据库使配置生效
[opengauss@fgedu.net.cn ~]$ gs_ctl restart -D /opengauss/fgdata
waiting for server to shut down…. done
server stopped
waiting for server to start…. done
server started
# 验证WAL归档是否生效
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “SELECT pg_switch_wal();
“
Password:
pg_switch_wal
学习交流加群风哥QQ113257174
—————
0/12345678
(1 row)
[opengauss@fgedu.net.cn ~]$ ls -la /opengauss/backup/wal/
total 16384
drwxr-xr-x 2 opengauss dbgrp 4096 Jan 1 12:34 .
drwxr-xr-x 3 opengauss dbgrp 4096 Jan 1 12:34 ..
-rw——- 1 opengauss dbgrp 16777216 Jan 1 12:34 000000010000000000000001
[opengauss@fgedu.net.cn ~]$ vim /opengauss/fgdata/postgresql.conf
# 修改以下参数
wal_level = logical
archive_mode = on
archive_command = ‘cp %p /opengauss/backup/wal/%f’
archive_timeout = 60
# 创建WAL归档目录
[opengauss@fgedu.net.cn ~]$ mkdir -p /opengauss/backup/wal
[opengauss@fgedu.net.cn ~]$ chown -R opengauss:dbgrp /opengauss/backup
# 重启数据库使配置生效
[opengauss@fgedu.net.cn ~]$ gs_ctl restart -D /opengauss/fgdata
waiting for server to shut down…. done
server stopped
waiting for server to start…. done
server started
# 验证WAL归档是否生效
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “SELECT pg_switch_wal();
“
Password:
pg_switch_wal
学习交流加群风哥QQ113257174
—————
0/12345678
(1 row)
[opengauss@fgedu.net.cn ~]$ ls -la /opengauss/backup/wal/
total 16384
drwxr-xr-x 2 opengauss dbgrp 4096 Jan 1 12:34 .
drwxr-xr-x 3 opengauss dbgrp 4096 Jan 1 12:34 ..
-rw——- 1 opengauss dbgrp 16777216 Jan 1 12:34 000000010000000000000001
3.2 执行增量备份
# 全量备份
[opengauss@fgedu.net.cn ~]$ gs_basebackup -D /opengauss/backup/full/20240101 -h 192.168.1.100 -p 5432 -U opengauss -F p -X stream
Password:
gs_basebackup: initiating base backup, waiting for checkpoint to complete
gs_basebackup: checkpoint completed
gs_basebackup: write-ahead log start point: 0/12345678
gs_basebackup: write-ahead log end point: 0/12345678
gs_basebackup: base backup completed, pg_wal directory size: 16 MB
# 插入新数据
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “INSERT INTO fgedu_employee (name, age, dept_id, salary) VALUES (‘Sun Qi’, 28, 1, 8000.00);
“
Password:
INSERT 0 1
# 切换WAL日志
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “SELECT pg_switch_wal();
“
Password:
pg_switch_wal
—————
0/12345679
(1 row)
# 查看WAL归档文件
[opengauss@fgedu.net.cn ~]$ ls -la /opengauss/backup/wal/
total 32768
drwxr-xr-x 2 opengauss dbgrp 4096 Jan 1 12:34 .
drwxr-xr-x 3 opengauss dbgrp 4096 Jan 1 12:34 ..
-rw——- 1 opengauss dbgrp 16777216 Jan 1 12:34 000000010000000000000001
-rw——- 1 opengauss dbgrp 16777216 Jan 1 12:34 000000010000000000000002
[opengauss@fgedu.net.cn ~]$ gs_basebackup -D /opengauss/backup/full/20240101 -h 192.168.1.100 -p 5432 -U opengauss -F p -X stream
Password:
gs_basebackup: initiating base backup, waiting for checkpoint to complete
gs_basebackup: checkpoint completed
gs_basebackup: write-ahead log start point: 0/12345678
gs_basebackup: write-ahead log end point: 0/12345678
gs_basebackup: base backup completed, pg_wal directory size: 16 MB
# 插入新数据
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “INSERT INTO fgedu_employee (name, age, dept_id, salary) VALUES (‘Sun Qi’, 28, 1, 8000.00);
“
Password:
INSERT 0 1
# 切换WAL日志
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “SELECT pg_switch_wal();
“
Password:
pg_switch_wal
—————
0/12345679
(1 row)
# 查看WAL归档文件
[opengauss@fgedu.net.cn ~]$ ls -la /opengauss/backup/wal/
total 32768
drwxr-xr-x 2 opengauss dbgrp 4096 Jan 1 12:34 .
drwxr-xr-x 3 opengauss dbgrp 4096 Jan 1 12:34 ..
-rw——- 1 opengauss dbgrp 16777216 Jan 1 12:34 000000010000000000000001
-rw——- 1 opengauss dbgrp 16777216 Jan 1 12:34 000000010000000000000002
更多视频教程www.fgedu.net.cn
3.3 执行时间点恢复
# 停止数据库
[opengauss@fgedu.net.cn ~]$ gs_ctl stop -D /opengauss/fgdata
waiting for server to shut down…. done
server stopped
# 清理数据目录
[opengauss@fgedu.net.cn ~]$ rm -rf /opengauss/fgdata/*
# 恢复全量备份
[opengauss@fgedu.net.cn ~]$ cp -r /opengauss/backup/full/20240101/* /opengauss/fgdata/
# 创建recovery.conf文件
[opengauss@fgedu.net.cn ~]$ vim /opengauss/fgdata/recovery.conf
restore_command = ‘cp /opengauss/backup/wal/%f %p’
recovery_target_time = ‘2024-01-01 12:34:56’
recovery_target_inclusive = true
# 启动数据库进行恢复
[opengauss@fgedu.net.cn ~]$ gs_ctl start -D /opengauss/fgdata
waiting for server to start…. done
server started
# 验证恢复结果
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “SELECT count(*) FROM fgedu_employee;
“
Password:
count
——-
4
(1 row)
[opengauss@fgedu.net.cn ~]$ gs_ctl stop -D /opengauss/fgdata
waiting for server to shut down…. done
server stopped
# 清理数据目录
[opengauss@fgedu.net.cn ~]$ rm -rf /opengauss/fgdata/*
# 恢复全量备份
[opengauss@fgedu.net.cn ~]$ cp -r /opengauss/backup/full/20240101/* /opengauss/fgdata/
# 创建recovery.conf文件
[opengauss@fgedu.net.cn ~]$ vim /opengauss/fgdata/recovery.conf
restore_command = ‘cp /opengauss/backup/wal/%f %p’
recovery_target_time = ‘2024-01-01 12:34:56’
recovery_target_inclusive = true
# 启动数据库进行恢复
[opengauss@fgedu.net.cn ~]$ gs_ctl start -D /opengauss/fgdata
waiting for server to start…. done
server started
# 验证恢复结果
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “SELECT count(*) FROM fgedu_employee;
“
Password:
count
——-
4
(1 row)
Part04-生产案例与实战讲解
4.1 增量备份实战
# 配置WAL归档
[opengauss@fgedu.net.cn ~]$ vim /opengauss/fgdata/postgresql.conf
# 修改以下参数
wal_level = logical
archive_mode = on
archive_command = ‘cp %p /opengauss/backup/wal/%f’
archive_timeout = 60
[opengauss@fgedu.net.cn ~]$ mkdir -p /opengauss/backup/wal
更多学习教程公众号风哥教程itpux_com
[opengauss@fgedu.net.cn ~]$ chown -R opengauss:dbgrp /opengauss/backup
[opengauss@fgedu.net.cn ~]$ gs_ctl restart -D /opengauss/fgdata
waiting for server to shut down…. done
server stopped
waiting for server to start…. done
server started
# 执行全量备份
[opengauss@fgedu.net.cn ~]$ gs_basebackup -D /opengauss/backup/full/$(date +%Y%m%d) -h 192.168.1.100 -p 5432 -U opengauss -F p -X stream
Password:
gs_basebackup: initiating base backup, waiting for checkpoint to complete
gs_basebackup: checkpoint completed
gs_basebackup: write-ahead log start point: 0/12345678
gs_basebackup: write-ahead log end point: 0/12345678
gs_basebackup: base backup completed, pg_wal directory size: 16 MB
# 模拟业务操作
[opengauss@fgedu.net.cn ~]$ for i in {1..10}; do gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “INSERT INTO fgedu_employee (name, age, dept_id, salary) VALUES (‘Employee$i’, $((20+i)), 1, $((5000+i*100)));”;
done
Password:
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
# 切换WAL日志
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “SELECT pg_switch_wal();
“
Password:
from DB视频:www.itpux.com
pg_switch_wal
—————
0/12345679
(1 row)
# 查看WAL归档文件
[opengauss@fgedu.net.cn ~]$ ls -la /opengauss/backup/wal/
total 32768
drwxr-xr-x 2 opengauss dbgrp 4096 Jan 1 12:34 .
drwxr-xr-x 3 opengauss dbgrp 4096 Jan 1 12:34 ..
-rw——- 1 opengauss dbgrp 16777216 Jan 1 12:34 000000010000000000000001
-rw——- 1 opengauss dbgrp 16777216 Jan 1 12:34 000000010000000000000002
[opengauss@fgedu.net.cn ~]$ vim /opengauss/fgdata/postgresql.conf
# 修改以下参数
wal_level = logical
archive_mode = on
archive_command = ‘cp %p /opengauss/backup/wal/%f’
archive_timeout = 60
[opengauss@fgedu.net.cn ~]$ mkdir -p /opengauss/backup/wal
更多学习教程公众号风哥教程itpux_com
[opengauss@fgedu.net.cn ~]$ chown -R opengauss:dbgrp /opengauss/backup
[opengauss@fgedu.net.cn ~]$ gs_ctl restart -D /opengauss/fgdata
waiting for server to shut down…. done
server stopped
waiting for server to start…. done
server started
# 执行全量备份
[opengauss@fgedu.net.cn ~]$ gs_basebackup -D /opengauss/backup/full/$(date +%Y%m%d) -h 192.168.1.100 -p 5432 -U opengauss -F p -X stream
Password:
gs_basebackup: initiating base backup, waiting for checkpoint to complete
gs_basebackup: checkpoint completed
gs_basebackup: write-ahead log start point: 0/12345678
gs_basebackup: write-ahead log end point: 0/12345678
gs_basebackup: base backup completed, pg_wal directory size: 16 MB
# 模拟业务操作
[opengauss@fgedu.net.cn ~]$ for i in {1..10}; do gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “INSERT INTO fgedu_employee (name, age, dept_id, salary) VALUES (‘Employee$i’, $((20+i)), 1, $((5000+i*100)));”;
done
Password:
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
# 切换WAL日志
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “SELECT pg_switch_wal();
“
Password:
from DB视频:www.itpux.com
pg_switch_wal
—————
0/12345679
(1 row)
# 查看WAL归档文件
[opengauss@fgedu.net.cn ~]$ ls -la /opengauss/backup/wal/
total 32768
drwxr-xr-x 2 opengauss dbgrp 4096 Jan 1 12:34 .
drwxr-xr-x 3 opengauss dbgrp 4096 Jan 1 12:34 ..
-rw——- 1 opengauss dbgrp 16777216 Jan 1 12:34 000000010000000000000001
-rw——- 1 opengauss dbgrp 16777216 Jan 1 12:34 000000010000000000000002
4.2 时间点恢复实战
# 模拟误操作
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “DELETE FROM fgedu_employee WHERE age > 30;
“
Password:
DELETE 5
# 查看当前时间
[opengauss@fgedu.net.cn ~]$ date
Mon Jan 1 12:34:56 CST 2024
# 停止数据库
[opengauss@fgedu.net.cn ~]$ gs_ctl stop -D /opengauss/fgdata
waiting for server to shut down…. done
server stopped
# 清理数据目录
[opengauss@fgedu.net.cn ~]$ rm -rf /opengauss/fgdata/*
# 恢复全量备份
[opengauss@fgedu.net.cn ~]$ cp -r /opengauss/backup/full/20240101/* /opengauss/fgdata/
# 创建recovery.conf文件
[opengauss@fgedu.net.cn ~]$ vim /opengauss/fgdata/recovery.conf
restore_command = ‘cp /opengauss/backup/wal/%f %p’
recovery_target_time = ‘2024-01-01 12:34:50’
recovery_target_inclusive = true
# 启动数据库进行恢复
[opengauss@fgedu.net.cn ~]$ gs_ctl start -D /opengauss/fgdata
waiting for server to start…. done
server started
# 验证恢复结果
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “SELECT count(*) FROM fgedu_employee;
“
Password:
count
——-
14
(1 row)
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “DELETE FROM fgedu_employee WHERE age > 30;
“
Password:
DELETE 5
# 查看当前时间
[opengauss@fgedu.net.cn ~]$ date
Mon Jan 1 12:34:56 CST 2024
# 停止数据库
[opengauss@fgedu.net.cn ~]$ gs_ctl stop -D /opengauss/fgdata
waiting for server to shut down…. done
server stopped
# 清理数据目录
[opengauss@fgedu.net.cn ~]$ rm -rf /opengauss/fgdata/*
# 恢复全量备份
[opengauss@fgedu.net.cn ~]$ cp -r /opengauss/backup/full/20240101/* /opengauss/fgdata/
# 创建recovery.conf文件
[opengauss@fgedu.net.cn ~]$ vim /opengauss/fgdata/recovery.conf
restore_command = ‘cp /opengauss/backup/wal/%f %p’
recovery_target_time = ‘2024-01-01 12:34:50’
recovery_target_inclusive = true
# 启动数据库进行恢复
[opengauss@fgedu.net.cn ~]$ gs_ctl start -D /opengauss/fgdata
waiting for server to start…. done
server started
# 验证恢复结果
[opengauss@fgedu.net.cn ~]$ gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “SELECT count(*) FROM fgedu_employee;
“
Password:
count
——-
14
(1 row)
4.3 备份策略优化
# 创建增量备份脚本
[opengauss@fgedu.net.cn ~]$ cat /opengauss/scripts/incremental_backup.sh
#!/bin/bash
# incremental_backup.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
# 备份目录
BACKUP_DIR=”/opengauss/backup”
DATE=$(date +%Y%m%d)
WEEKDAY=$(date +%u)
# 创建备份目录
mkdir -p $BACKUP_DIR/full
mkdir -p $BACKUP_DIR/wal
# 全量备份(每周日)
if [ $WEEKDAY -eq 7 ]; then
echo “Performing full backup…”
gs_basebackup -D $BACKUP_DIR/full/$DATE -h 192.168.1.100 -p 5432 -U opengauss -F p -X stream
# 清理30天前的全量备份
find $BACKUP_DIR/full -type d -mtime +30 -exec rm -rf {} \;
fi
# 切换WAL日志,确保归档
echo “Switching WAL log…”
gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “SELECT pg_switch_wal();
“
# 清理7天前的WAL日志
find $BACKUP_DIR/wal -name “*.backup” -o -name “000000*” | sort | head -n -100 | xargs rm -f
# 设置定时任务
[opengauss@fgedu.net.cn ~]$ crontab -e
# 每天凌晨2点执行增量备份
0 2 * * * /opengauss/scripts/incremental_backup.sh >> /opengauss/logs/backup.log 2>&1
[opengauss@fgedu.net.cn ~]$ cat /opengauss/scripts/incremental_backup.sh
#!/bin/bash
# incremental_backup.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
# 备份目录
BACKUP_DIR=”/opengauss/backup”
DATE=$(date +%Y%m%d)
WEEKDAY=$(date +%u)
# 创建备份目录
mkdir -p $BACKUP_DIR/full
mkdir -p $BACKUP_DIR/wal
# 全量备份(每周日)
if [ $WEEKDAY -eq 7 ]; then
echo “Performing full backup…”
gs_basebackup -D $BACKUP_DIR/full/$DATE -h 192.168.1.100 -p 5432 -U opengauss -F p -X stream
# 清理30天前的全量备份
find $BACKUP_DIR/full -type d -mtime +30 -exec rm -rf {} \;
fi
# 切换WAL日志,确保归档
echo “Switching WAL log…”
gsql -h 192.168.1.100 -p 5432 -U opengauss -d fgedudb -c “SELECT pg_switch_wal();
“
# 清理7天前的WAL日志
find $BACKUP_DIR/wal -name “*.backup” -o -name “000000*” | sort | head -n -100 | xargs rm -f
# 设置定时任务
[opengauss@fgedu.net.cn ~]$ crontab -e
# 每天凌晨2点执行增量备份
0 2 * * * /opengauss/scripts/incremental_backup.sh >> /opengauss/logs/backup.log 2>&1
Part05-风哥经验总结与分享
5.1 增量备份最佳实践
- 备份策略:
- 结合全量备份和增量备份
- 根据数据变化频率调整备份频率
- 定期验证备份的有效性
- WAL日志管理:
- 启用WAL归档
- 设置合适的WAL段大小
- 定期清理过期的WAL日志
- 存储管理:
- 使用高性能存储
- 异地存储备份文件
- 确保存储空间足够
5.2 时间点恢复最佳实践
- 恢复策略:
- 制定详细的恢复计划
- 定期演练恢复过程
- 明确恢复步骤和责任人
- 时间点选择:
- 选择合适的恢复时间点
- 确保恢复点的一致性
- 考虑业务需求和数据完整性
- 恢复验证:
- 恢复后验证数据的完整性
- 检查数据库的运行状态
- 测试应用的正常运行
5.3 常见问题与解决方案
常见增量备份与时间点恢复问题及解决方法
- 问题1:WAL归档失败
- 症状:WAL日志无法归档
- 解决方案:检查归档目录权限;检查存储空间是否足够;检查归档命令是否正确
- 问题2:增量备份恢复失败
- 症状:无法应用增量备份
- 解决方案:检查全量备份是否完整;检查WAL日志是否连续;检查恢复配置是否正确
- 问题3:时间点恢复不准确
- 症状:恢复到错误的时间点
- 解决方案:确保WAL日志完整;选择正确的恢复时间点;检查恢复配置是否正确
- 问题4:WAL日志占用空间过大
- 症状:WAL日志目录占用大量空间
- 解决方案:定期清理过期的WAL日志;调整WAL日志保留策略;使用压缩存储
- 问题5:恢复时间过长
- 症状:恢复过程耗时过长
- 解决方案:使用并行恢复;优化恢复参数;使用快速恢复技术
风哥提示:增量备份和时间点恢复是数据库管理的重要功能,正确配置和使用这些功能可以提高数据库的安全性和可靠性。在生产环境中,应该制定合理的备份策略,定期执行备份,确保在发生灾难时能够快速恢复数据库。同时,应该注意WAL日志的管理和存储空间的监控,确保备份和恢复过程的顺利进行。
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
