1. 首页 > 国产数据库教程 > YashanDB教程 > 正文

yashanb教程FG194-YashanDB长事务处理

本文档风哥主要介绍YashanDB长事务处理相关知识,包括YashanDB长事务的概念、影响、原因、处理规划、预防措施、实现、监控、故障排查、生产案例与实战讲解等内容,风哥教程参考YashanDB官方文档性能调优内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。

Part01-基础概念与理论知识

1.1 YashanDB长事务的概念

YashanDB长事务是指执行时间较长的事务,通常是指执行时间超过一定阈值(如10秒、1分钟或更长)的事务。长事务可能会占用数据库资源,影响其他事务的执行,甚至导致数据库性能下降。更多视频教程www.fgedu.net.cn

YashanDB长事务的定义:

  • 长事务是指执行时间较长的事务
  • 长事务的阈值通常根据业务需求和系统性能来定义
  • 长事务可能会占用数据库资源,影响其他事务的执行
  • 长事务可能导致锁等待、死锁等问题

1.2 YashanDB长事务的影响

YashanDB长事务的影响包括:

  • 锁竞争:长事务会持有锁的时间较长,导致其他事务等待
  • 资源占用:长事务会占用数据库连接、内存等资源
  • 性能下降:长事务会导致数据库性能下降,影响整体系统性能
  • 回滚开销:长事务的回滚会消耗大量资源和时间
  • 日志增长:长事务会产生大量的 redo 日志,导致日志文件增长过快
  • 备份影响:长事务会影响数据库备份的执行

1.3 YashanDB长事务的原因

YashanDB长事务的常见原因包括:

  • 大数据量操作:处理大量数据的操作,如批量更新、删除或插入
  • 复杂查询:执行复杂的查询,如多表关联、聚合操作等
  • 锁等待:事务等待其他事务释放锁
  • 外部资源:事务依赖外部资源,如网络I/O、文件I/O等
  • 事务设计不合理:事务范围过大,包含了不必要的操作
  • 系统资源不足:CPU、内存、磁盘I/O等系统资源不足
风哥提示:长事务是数据库性能优化中的重要问题,需要引起足够的重视。在设计和开发数据库应用时,应尽量避免长事务的发生,合理设计事务范围,确保事务能够快速提交或回滚。学习交流加群风哥微信: itpux-com

Part02-生产环境规划与建议

2.1 YashanDB长事务处理规划

YashanDB长事务处理规划建议:

# 长事务处理规划原则
– 预防为主:通过合理的设计和优化,预防长事务的发生
– 监控及时:建立长事务监控机制,及时发现长事务
– 处理高效:建立长事务处理流程,确保长事务能够被及时处理
– 影响最小化:采取措施,将长事务的影响降到最低

# 长事务处理流程
1. 监控:通过监控系统及时发现长事务
2. 分析:分析长事务的原因和影响
3. 处理:根据长事务的类型和影响,采取相应的处理措施
4. 优化:针对长事务的原因,进行优化,避免类似问题的发生
5. 记录:记录长事务的处理过程和结果,为后续优化提供参考

# 长事务处理策略
– 预防策略:合理设计事务范围,优化SQL语句,避免大数据量操作
– 监控策略:建立长事务监控机制,设置合理的告警阈值
– 处理策略:对长事务进行分析和处理,必要时终止长事务
– 优化策略:针对长事务的原因,进行系统优化和应用优化

2.2 YashanDB长事务预防措施

YashanDB长事务预防措施建议:

# 长事务预防措施

# 1. 事务设计优化
– 缩小事务范围:将大事务拆分为多个小事务
– 避免不必要的操作:只包含必要的操作在事务中
– 合理设置事务隔离级别:根据业务需求选择合适的隔离级别
– 及时提交或回滚:避免事务长时间处于未提交状态

# 2. SQL语句优化
– 优化查询语句:使用合适的索引,避免全表扫描
– 优化批量操作:使用批量处理,减少事务次数
– 避免复杂查询:将复杂查询拆分为多个简单查询
– 使用绑定变量:减少硬解析,提高执行效率

# 3. 系统配置优化
– 合理设置超时参数:设置事务超时时间,避免事务无限期执行
– 优化内存配置:增加共享池和PGA的大小
– 优化I/O配置:使用高性能存储,提高I/O速度
– 合理设置并行度:根据系统资源设置合适的并行度

# 4. 应用程序优化
– 异步处理:将耗时操作改为异步处理
– 批量处理:对大量数据的操作采用批量处理
– 连接池管理:合理使用连接池,避免连接泄漏
– 错误处理:及时处理异常,避免事务长时间挂起

# 5. 监控和告警
– 建立长事务监控机制:监控事务的执行时间
– 设置合理的告警阈值:当事务执行时间超过阈值时告警
– 定期分析:定期分析长事务,找出优化机会
– 性能基准:建立性能基准,及时发现性能异常

2.3 YashanDB长事务处理最佳实践

YashanDB长事务处理最佳实践:

# 长事务处理最佳实践

# 1. 事务设计
– 保持事务简短:事务应尽可能简短,只包含必要的操作
– 避免在事务中进行非数据库操作:如网络I/O、文件I/O等
– 合理设置事务隔离级别:根据业务需求选择合适的隔离级别
– 及时提交或回滚:避免事务长时间处于未提交状态

# 2. SQL优化
– 使用绑定变量:减少硬解析,提高执行效率
– 优化索引:确保查询使用合适的索引
– 避免全表扫描:对大表进行操作时,使用索引或分区
– 优化批量操作:使用批量插入、更新和删除

# 3. 系统配置
– 设置合理的超时参数:如事务超时、语句超时
– 优化内存配置:增加共享池和PGA的大小
– 优化I/O配置:使用RAID、SSD等高性能存储
– 合理设置并行度:根据系统资源设置合适的并行度

# 4. 监控和管理
– 建立长事务监控机制:监控事务的执行时间和状态
– 设置合理的告警阈值:当事务执行时间超过阈值时告警
– 定期分析长事务:找出长事务的原因和优化机会
– 建立长事务处理流程:确保长事务能够被及时处理

# 5. 应急处理
– 准备应急方案:当长事务影响系统性能时,能够快速处理
– 建立回滚机制:当长事务无法正常完成时,能够安全回滚
– 定期演练:定期演练长事务的处理流程,确保应急方案的有效性
– 文档化:记录长事务的处理过程和结果,为后续优化提供参考

生产环境建议:长事务处理需要从设计、开发、运维等多个角度入手,采取综合措施预防和处理长事务。建议建立完善的长事务监控和处理机制,确保系统的稳定运行。学习交流加群风哥QQ113257174

Part03-生产环境项目实施方案

3.1 YashanDB长事务处理实现

3.1.1 检测YashanDB长事务

# 检测YashanDB长事务

# 1. 使用v$session视图检测长事务
SQL> SELECT s.sid, s.serial#, s.username, s.status, s.sql_id,
(SYSDATE – s.logon_time) * 24 * 60 * 60 AS session_age_seconds,
(SYSDATE – t.start_time) * 24 * 60 * 60 AS transaction_age_seconds
FROM v$session s
JOIN v$transaction t ON s.taddr = t.addr
WHERE (SYSDATE – t.start_time) * 24 * 60 > 1 — 超过1分钟的事务
ORDER BY transaction_age_seconds DESC;

SID SERIAL# USERNAME STATUS SQL_ID SESSION_AGE_SECONDS TRANSACTION_AGE_SECONDS
——- ———- ———- ——– ————- ——————- ————————
123 456 FGEDU ACTIVE a1b2c3d4e5f6 3600 600
234 567 FGEDU ACTIVE f6e5d4c3b2a1 1800 300

# 2. 使用v$active_session_history视图检测长事务
SQL> SELECT session_id, sql_id,
MAX(elapsed_time) / 1000000 AS max_elapsed_seconds
FROM v$active_session_history
WHERE sample_time > SYSDATE – 1/24 — 最近1小时
GROUP BY session_id, sql_id
HAVING MAX(elapsed_time) / 1000000 > 60 — 超过60秒的SQL
ORDER BY max_elapsed_seconds DESC;

SESSION_ID SQL_ID MAX_ELAPSED_SECONDS
———- ————- ——————
123 a1b2c3d4e5f6 120
234 f6e5d4c3b2a1 90

# 3. 使用DBA_HIST_ACTIVE_SESS_HISTORY视图检测长事务
SQL> SELECT session_id, sql_id,
MAX(elapsed_time) / 1000000 AS max_elapsed_seconds
FROM dba_hist_active_sess_history
WHERE sample_time > SYSDATE – 7 — 最近7天
GROUP BY session_id, sql_id
HAVING MAX(elapsed_time) / 1000000 > 60 — 超过60秒的SQL
ORDER BY max_elapsed_seconds DESC;

SESSION_ID SQL_ID MAX_ELAPSED_SECONDS
———- ————- ——————
123 a1b2c3d4e5f6 180
234 f6e5d4c3b2a1 150

3.1.2 处理YashanDB长事务

# 处理YashanDB长事务

# 1. 分析长事务
SQL> SELECT s.sid, s.serial#, s.username, s.machine, s.program,
t.start_time, t.used_ublk, t.used_urec,
q.sql_text
FROM v$session s
JOIN v$transaction t ON s.taddr = t.addr
JOIN v$sql q ON s.sql_id = q.sql_id
WHERE (SYSDATE – t.start_time) * 24 * 60 > 1 — 超过1分钟的事务
ORDER BY (SYSDATE – t.start_time) DESC;

SID SERIAL# USERNAME MACHINE PROGRAM START_TIME USED_UBLK USED_UREC SQL_TEXT
——- ———- ———- ———— —————- ————— ———- ———- —————————————-
123 456 FGEDU fgedu.net.cn sqlplus@fgedu.net 2026-04-01 10:00:00 100 1000 UPDATE fgedu.orders SET status = ‘COMPLETED’ WHERE order_date < SYSDATE - 30; # 2. 终止长事务 SQL> ALTER SYSTEM KILL SESSION ‘123,456’ IMMEDIATE;

System altered.

# 3. 优化长事务
# 对于批量更新操作,使用批量处理
SQL> BEGIN
2 FOR i IN 1..10 LOOP
3 UPDATE fgedu.orders
4 SET status = ‘COMPLETED’
5 WHERE order_date < SYSDATE - 30 6 AND rownum <= 10000; 7 COMMIT; 8 EXIT WHEN SQL%ROWCOUNT = 0; 9 END LOOP; 10 END; 11 / PL/SQL procedure successfully completed. # 4. 设置事务超时 SQL> ALTER SYSTEM SET resource_limit = TRUE;

System altered.

SQL> CREATE PROFILE long_transaction_profile LIMIT
2 IDLE_TIME 30
3 CONNECT_TIME 120;

Profile created.

SQL> ALTER USER fgedu PROFILE long_transaction_profile;

User altered.

3.1.3 优化YashanDB长事务

# 优化YashanDB长事务

# 1. 优化SQL语句
# 原SQL
UPDATE fgedu.orders SET status = ‘COMPLETED’ WHERE order_date < SYSDATE - 30; # 优化后SQL CREATE INDEX idx_orders_order_date ON fgedu.orders(order_date); BEGIN FOR i IN 1..10 LOOP UPDATE fgedu.orders SET status = 'COMPLETED' WHERE order_date < SYSDATE - 30 AND rownum <= 10000; COMMIT; EXIT WHEN SQL%ROWCOUNT = 0; END LOOP; END; / # 2. 优化事务设计 # 原事务 BEGIN -- 操作1 UPDATE fgedu.orders SET status = 'COMPLETED' WHERE order_date < SYSDATE - 30; -- 操作2 INSERT INTO fgedu.order_history SELECT * FROM fgedu.orders WHERE status = 'COMPLETED'; -- 操作3 DELETE FROM fgedu.orders WHERE status = 'COMPLETED'; COMMIT; END; / # 优化后事务 -- 操作1 BEGIN FOR i IN 1..10 LOOP UPDATE fgedu.orders SET status = 'COMPLETED' WHERE order_date < SYSDATE - 30 AND rownum <= 10000; COMMIT; EXIT WHEN SQL%ROWCOUNT = 0; END LOOP; END; / -- 操作2 BEGIN FOR i IN 1..10 LOOP INSERT INTO fgedu.order_history SELECT * FROM fgedu.orders WHERE status = 'COMPLETED' AND rownum <= 10000; COMMIT; EXIT WHEN SQL%ROWCOUNT = 0; END LOOP; END; / -- 操作3 BEGIN FOR i IN 1..10 LOOP DELETE FROM fgedu.orders WHERE status = 'COMPLETED' AND rownum <= 10000; COMMIT; EXIT WHEN SQL%ROWCOUNT = 0; END LOOP; END; / # 3. 优化系统配置 # 增加共享池大小 SQL> ALTER SYSTEM SET shared_pool_size = 2G SCOPE=spfile;

# 增加PGA大小
SQL> ALTER SYSTEM SET pga_aggregate_target = 2G SCOPE=spfile;

# 设置事务超时
SQL> ALTER SYSTEM SET resource_limit = TRUE;

SQL> CREATE PROFILE long_transaction_profile LIMIT
2 IDLE_TIME 30
3 CONNECT_TIME 120;

SQL> ALTER USER fgedu PROFILE long_transaction_profile;

3.2 YashanDB长事务监控

3.2.1 YashanDB长事务监控命令

# 长事务监控命令

# 1. 监控当前活跃事务
SQL> SELECT s.sid, s.serial#, s.username, s.status, s.sql_id,
(SYSDATE – s.logon_time) * 24 * 60 * 60 AS session_age_seconds,
(SYSDATE – t.start_time) * 24 * 60 * 60 AS transaction_age_seconds
FROM v$session s
JOIN v$transaction t ON s.taddr = t.addr
WHERE (SYSDATE – t.start_time) * 24 * 60 > 1 — 超过1分钟的事务
ORDER BY transaction_age_seconds DESC;

# 2. 监控SQL执行情况
SQL> SELECT sql_id, elapsed_time, buffer_gets, executions,
elapsed_time / executions / 1000000 AS avg_elapsed_seconds
FROM v$sql
WHERE executions > 0
AND elapsed_time / 1000000 > 60 — 超过60秒的SQL
ORDER BY elapsed_time DESC;

# 3. 监控锁等待
SQL> SELECT l.session_id, l.lock_type, l.mode_held, l.mode_requested,
s.username, s.sql_id, (SYSDATE – s.logon_time) * 24 * 60 AS minutes_active
FROM dba_locks l
JOIN v$session s ON l.session_id = s.sid
WHERE l.blocking_others = ‘Blocking’
ORDER BY minutes_active DESC;

# 4. 监控事务回滚
SQL> SELECT s.sid, s.serial#, s.username, r.used_ublk, r.used_urec,
r.start_time, (SYSDATE – r.start_time) * 24 * 60 AS minutes_rolling_back
FROM v$session s
JOIN v$rollstat r ON s.taddr = r.xid
WHERE r.status = ‘ACTIVE’
ORDER BY minutes_rolling_back DESC;

3.2.2 YashanDB长事务监控脚本

#!/bin/bash
# long_transaction_monitor.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`

# 长事务监控脚本

# 输出文件
output_file=”/tmp/long_transaction_monitor_$(date +%Y%m%d_%H%M%S).log”

echo “开始监控长事务” > ${output_file}
echo “监控时间: $(date)” >> ${output_file}
echo “” >> ${output_file}

# 监控当前活跃事务
echo “===== 当前活跃事务 ====” >> ${output_file}
sqlplus -s / as sysdba << EOF >> ${output_file}
SELECT s.sid, s.serial#, s.username, s.status, s.sql_id,
(SYSDATE – s.logon_time) * 24 * 60 * 60 AS session_age_seconds,
(SYSDATE – t.start_time) * 24 * 60 * 60 AS transaction_age_seconds
FROM v\$session s
JOIN v\$transaction t ON s.taddr = t.addr
WHERE (SYSDATE – t.start_time) * 24 * 60 > 1 — 超过1分钟的事务
ORDER BY transaction_age_seconds DESC;
EXIT;
EOF
echo “” >> ${output_file}

# 监控SQL执行情况
echo “===== SQL执行情况 ====” >> ${output_file}
sqlplus -s / as sysdba << EOF >> ${output_file}
SELECT sql_id, elapsed_time, buffer_gets, executions,
elapsed_time / executions / 1000000 AS avg_elapsed_seconds
FROM v\$sql
WHERE executions > 0
AND elapsed_time / 1000000 > 60 — 超过60秒的SQL
ORDER BY elapsed_time DESC
FETCH FIRST 10 ROWS ONLY;
EXIT;
EOF
echo “” >> ${output_file}

# 监控锁等待
echo “===== 锁等待 ====” >> ${output_file}
sqlplus -s / as sysdba << EOF >> ${output_file}
SELECT l.session_id, l.lock_type, l.mode_held, l.mode_requested,
s.username, s.sql_id, (SYSDATE – s.logon_time) * 24 * 60 AS minutes_active
FROM dba_locks l
JOIN v\$session s ON l.session_id = s.sid
WHERE l.blocking_others = ‘Blocking’
ORDER BY minutes_active DESC;
EXIT;
EOF
echo “” >> ${output_file}

echo “长事务监控完成,结果保存至:${output_file}” >> ${output_file}
echo “长事务监控完成,结果保存至:${output_file}”

# 检查是否有长事务
long_transaction_count=$(sqlplus -s / as sysdba << EOF SET HEAD OFF SET FEEDBACK OFF SELECT COUNT(*) FROM v\$session s JOIN v\$transaction t ON s.taddr = t.addr WHERE (SYSDATE - t.start_time) * 24 * 60 > 5;
EXIT;
EOF
)

if [ $long_transaction_count -gt 0 ]; then
echo “发现长事务!数量: $long_transaction_count”
# 发送告警
echo “长事务告警:发现 $long_transaction_count 个长事务” | mail -s “YashanDB长事务告警” admin@fgedu.net.cn
fi

3.3 YashanDB长事务故障排查

3.3.1 YashanDB长事务故障排查步骤

# 长事务故障排查步骤

# 1. 发现长事务
– 通过监控系统发现长事务
– 通过告警信息发现长事务
– 通过用户反馈发现长事务

# 2. 分析长事务
– 查看长事务的SQL语句
– 查看长事务的执行计划
– 查看长事务的资源使用情况
– 查看长事务的锁等待情况

# 3. 确定长事务的原因
– 大数据量操作
– 复杂查询
– 锁等待
– 外部资源依赖
– 系统资源不足

# 4. 采取处理措施
– 优化SQL语句
– 拆分长事务
– 终止长事务
– 增加系统资源
– 调整系统配置

# 5. 验证处理结果
– 检查长事务是否已结束
– 检查系统性能是否恢复
– 检查是否有其他影响

# 6. 预防措施
– 优化应用程序设计
– 加强监控和告警
– 定期性能分析
– 建立长事务处理流程

3.3.2 YashanDB长事务故障排查工具

# 长事务故障排查工具

# 1. 数据库视图
– v$session:查看会话信息
– v$transaction:查看事务信息
– v$sql:查看SQL语句信息
– v$active_session_history:查看活跃会话历史
– dba_locks:查看锁信息
– v$rollstat:查看回滚段信息

# 2. 诊断工具
– AWR (Automatic Workload Repository):自动工作负载仓库
– ASH (Active Session History):活跃会话历史
– ADDM (Automatic Database Diagnostic Monitor):自动数据库诊断监控器
– SQL Tuning Advisor:SQL调优顾问
– Enterprise Manager:企业管理器

# 3. 操作系统工具
– top:查看系统资源使用情况
– iostat:查看I/O使用情况
– vmstat:查看虚拟内存使用情况
– netstat:查看网络使用情况

# 4. 第三方工具
– Toad:数据库管理工具
– SQL Developer:SQL开发工具
– Navicat:数据库管理工具
– Prometheus + Grafana:监控和可视化工具

风哥提示:长事务故障排查需要综合使用多种工具和方法,从多个角度分析问题。建议建立完善的故障排查流程,确保能够快速定位和解决长事务问题。更多学习教程公众号风哥教程itpux_com

Part04-生产案例与实战讲解

4.1 YashanDB长事务处理案例一

案例背景:某企业数据库系统出现长事务,导致系统性能下降,需要及时处理。

# 案例配置

# 1. 环境信息
– 数据库版本:YashanDB 19c
– 操作系统:Oracle Linux 9.3
– 硬件配置:8核CPU,32GB内存,1TB SSD
– 业务类型:OLTP

# 2. 问题描述
– 系统性能下降,用户反映操作缓慢
– 监控系统告警,发现长事务
– 数据库连接数增加,资源使用率高

# 3. 故障排查

# 查看长事务
SQL> SELECT s.sid, s.serial#, s.username, s.status, s.sql_id,
(SYSDATE – s.logon_time) * 24 * 60 * 60 AS session_age_seconds,
(SYSDATE – t.start_time) * 24 * 60 * 60 AS transaction_age_seconds
FROM v$session s
JOIN v$transaction t ON s.taddr = t.addr
WHERE (SYSDATE – t.start_time) * 24 * 60 > 1 — 超过1分钟的事务
ORDER BY transaction_age_seconds DESC;

SID SERIAL# USERNAME STATUS SQL_ID SESSION_AGE_SECONDS TRANSACTION_AGE_SECONDS
——- ———- ———- ——– ————- ——————- ————————
123 456 FGEDU ACTIVE a1b2c3d4e5f6 3600 600

# 查看长事务的SQL语句
SQL> SELECT sql_text FROM v$sql WHERE sql_id = ‘a1b2c3d4e5f6’;

SQL_TEXT
—————————————-
UPDATE fgedu.orders SET status = ‘COMPLETED’ WHERE order_date < SYSDATE - 30; # 查看执行计划 SQL> EXPLAIN PLAN FOR UPDATE fgedu.orders SET status = ‘COMPLETED’ WHERE order_date < SYSDATE - 30; Explained. SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
—————————————-
Plan hash value: 1234567890

——————————————————————————-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
——————————————————————————-
| 0 | UPDATE STATEMENT | | 100K| 1000K| 1000 (5)| 00:00:01 |
| 1 | UPDATE | ORDERS | | | | |
| 2 | FULL TABLE SCAN| ORDERS | 100K| 1000K| 1000 (5)| 00:00:01 |
——————————————————————————-

# 4. 处理措施

# 优化SQL语句
SQL> CREATE INDEX idx_orders_order_date ON fgedu.orders(order_date);

Index created.

# 拆分长事务
SQL> BEGIN
2 FOR i IN 1..10 LOOP
3 UPDATE fgedu.orders
4 SET status = ‘COMPLETED’
5 WHERE order_date < SYSDATE - 30 6 AND rownum <= 10000; 7 COMMIT; 8 EXIT WHEN SQL%ROWCOUNT = 0; 9 END LOOP; 10 END; 11 / PL/SQL procedure successfully completed. # 终止长事务 SQL> ALTER SYSTEM KILL SESSION ‘123,456’ IMMEDIATE;

System altered.

# 5. 验证结果

# 检查长事务是否已结束
SQL> SELECT s.sid, s.serial#, s.username, s.status, s.sql_id,
(SYSDATE – s.logon_time) * 24 * 60 * 60 AS session_age_seconds,
(SYSDATE – t.start_time) * 24 * 60 * 60 AS transaction_age_seconds
FROM v$session s
JOIN v$transaction t ON s.taddr = t.addr
WHERE (SYSDATE – t.start_time) * 24 * 60 > 1;

no rows selected

# 检查系统性能是否恢复
$ sar -u 1 5

Linux 5.4.0-80-generic (fgedu.net.cn) 04/01/2026 _x86_64_ (8 CPU)

10:00:00 AM CPU %user %nice %system %iowait %steal %idle
10:00:01 AM all 5.23 0.00 1.25 0.00 0.00 93.52
10:00:02 AM all 4.88 0.00 1.12 0.00 0.00 93.99
10:00:03 AM all 5.12 0.00 1.35 0.00 0.00 93.53
10:00:04 AM all 4.95 0.00 1.28 0.00 0.00 93.77
10:00:05 AM all 5.32 0.00 1.45 0.00 0.00 93.23
Average: all 5.10 0.00 1.31 0.00 0.00 93.59

# 6. 预防措施

# 优化应用程序设计
– 拆分大事务为小事务
– 使用批量处理处理大量数据
– 合理设置事务隔离级别

# 加强监控和告警
– 配置长事务监控
– 设置合理的告警阈值
– 定期分析长事务

# 系统配置优化
– 增加共享池和PGA大小
– 设置事务超时参数
– 优化I/O配置

4.2 YashanDB长事务处理案例二

案例背景:某电商系统在大促期间出现长事务,导致系统响应缓慢,需要及时处理。

# 案例配置

# 1. 环境信息
– 数据库版本:YashanDB 19c
– 操作系统:Oracle Linux 9.3
– 硬件配置:16核CPU,64GB内存,2TB SSD
– 业务类型:OLTP,大促期间高并发

# 2. 问题描述
– 大促期间系统响应缓慢
– 监控系统告警,发现大量长事务
– 数据库连接数达到上限,资源使用率高

# 3. 故障排查

# 查看长事务
SQL> SELECT s.sid, s.serial#, s.username, s.status, s.sql_id,
(SYSDATE – s.logon_time) * 24 * 60 * 60 AS session_age_seconds,
(SYSDATE – t.start_time) * 24 * 60 * 60 AS transaction_age_seconds
FROM v$session s
JOIN v$transaction t ON s.taddr = t.addr
WHERE (SYSDATE – t.start_time) * 24 * 60 > 1 — 超过1分钟的事务
ORDER BY transaction_age_seconds DESC;

SID SERIAL# USERNAME STATUS SQL_ID SESSION_AGE_SECONDS TRANSACTION_AGE_SECONDS
——- ———- ———- ——– ————- ——————- ————————
123 456 FGEDU ACTIVE a1b2c3d4e5f6 3600 600
234 567 FGEDU ACTIVE f6e5d4c3b2a1 1800 300
345 678 FGEDU ACTIVE g7h8i9j0k1l2 1200 200

# 查看长事务的SQL语句
SQL> SELECT sql_text FROM v$sql WHERE sql_id = ‘a1b2c3d4e5f6’;

SQL_TEXT
—————————————-
INSERT INTO fgedu.order_items SELECT * FROM fgedu.temp_order_items;

SQL> SELECT sql_text FROM v$sql WHERE sql_id = ‘f6e5d4c3b2a1’;

SQL_TEXT
—————————————-
UPDATE fgedu.orders SET total_amount = (SELECT SUM(price * quantity) FROM fgedu.order_items WHERE order_id = orders.order_id);

# 查看执行计划
SQL> EXPLAIN PLAN FOR INSERT INTO fgedu.order_items SELECT * FROM fgedu.temp_order_items;

Explained.

SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
—————————————-
Plan hash value: 1234567890

——————————————————————————-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
——————————————————————————-
| 0 | INSERT STATEMENT | | 10M| 100M| 10000 (5)| 00:00:01 |
| 1 | LOAD TABLE CONVENTIONAL | ORDER_ITEMS | | | | |
| 2 | TABLE ACCESS FULL| TEMP_ORDER_ITEMS | 10M| 100M| 10000 (5)| 00:00:01 |
——————————————————————————-

# 4. 处理措施

# 优化SQL语句
# 对于批量插入,使用批量处理
SQL> BEGIN
2 FOR i IN 1..100 LOOP
3 INSERT INTO fgedu.order_items
4 SELECT * FROM fgedu.temp_order_items
5 WHERE rownum <= 100000; 6 COMMIT; 7 DELETE FROM fgedu.temp_order_items WHERE rownum <= 100000; 8 COMMIT; 9 EXIT WHEN SQL%ROWCOUNT = 0; 10 END LOOP; 11 END; 12 / PL/SQL procedure successfully completed. # 优化UPDATE语句,使用索引 SQL> CREATE INDEX idx_order_items_order_id ON fgedu.order_items(order_id);

Index created.

SQL> UPDATE /*+ PARALLEL(4) */ fgedu.orders
SET total_amount = (SELECT SUM(price * quantity)
FROM fgedu.order_items
WHERE order_id = orders.order_id);

# 终止长事务
SQL> ALTER SYSTEM KILL SESSION ‘123,456’ IMMEDIATE;
SQL> ALTER SYSTEM KILL SESSION ‘234,567’ IMMEDIATE;
SQL> ALTER SYSTEM KILL SESSION ‘345,678’ IMMEDIATE;

# 5. 验证结果

# 检查长事务是否已结束
SQL> SELECT s.sid, s.serial#, s.username, s.status, s.sql_id,
(SYSDATE – s.logon_time) * 24 * 60 * 60 AS session_age_seconds,
(SYSDATE – t.start_time) * 24 * 60 * 60 AS transaction_age_seconds
FROM v$session s
JOIN v$transaction t ON s.taddr = t.addr
WHERE (SYSDATE – t.start_time) * 24 * 60 > 1;

no rows selected

# 检查系统性能是否恢复
$ sar -u 1 5

Linux 5.4.0-80-generic (fgedu.net.cn) 04/01/2026 _x86_64_ (16 CPU)

10:00:00 AM CPU %user %nice %system %iowait %steal %idle
10:00:01 AM all 15.23 0.00 3.25 0.00 0.00 81.52
10:00:02 AM all 14.88 0.00 3.12 0.00 0.00 81.99
10:00:03 AM all 15.12 0.00 3.35 0.00 0.00 81.53
10:00:04 AM all 14.95 0.00 3.28 0.00 0.00 81.77
10:00:05 AM all 15.32 0.00 3.45 0.00 0.00 81.23
Average: all 15.10 0.00 3.31 0.00 0.00 81.59

# 6. 预防措施

# 优化应用程序设计
– 使用批量处理处理大量数据
– 避免在事务中进行大量数据操作
– 合理设置事务隔离级别

# 加强监控和告警
– 配置长事务监控
– 设置合理的告警阈值
– 大促期间安排专人监控

# 系统配置优化
– 增加共享池和PGA大小
– 设置事务超时参数
– 优化I/O配置,使用RAID 10

4.3 YashanDB长事务处理案例三

案例背景:某金融系统出现长事务,导致数据库备份失败,需要及时处理。

# 案例配置

# 1. 环境信息
– 数据库版本:YashanDB 19c
– 操作系统:Oracle Linux 9.3
– 硬件配置:12核CPU,48GB内存,1.5TB SSD
– 业务类型:OLTP,金融交易

# 2. 问题描述
– 数据库备份失败,报错”ORA-01555: snapshot too old”
– 监控系统告警,发现长事务
– 数据库性能下降,交易响应缓慢

# 3. 故障排查

# 查看长事务
SQL> SELECT s.sid, s.serial#, s.username, s.status, s.sql_id,
(SYSDATE – s.logon_time) * 24 * 60 * 60 AS session_age_seconds,
(SYSDATE – t.start_time) * 24 * 60 * 60 AS transaction_age_seconds
FROM v$session s
JOIN v$transaction t ON s.taddr = t.addr
WHERE (SYSDATE – t.start_time) * 24 * 60 > 1 — 超过1分钟的事务
ORDER BY transaction_age_seconds DESC;

SID SERIAL# USERNAME STATUS SQL_ID SESSION_AGE_SECONDS TRANSACTION_AGE_SECONDS
——- ———- ———- ——– ————- ——————- ————————
123 456 FGEDU ACTIVE a1b2c3d4e5f6 7200 3600

# 查看长事务的SQL语句
SQL> SELECT sql_text FROM v$sql WHERE sql_id = ‘a1b2c3d4e5f6’;

SQL_TEXT
—————————————-
BEGIN
FOR i IN 1..1000 LOOP
UPDATE fgedu.transactions SET status = ‘COMPLETED’ WHERE transaction_id = i;
— 模拟外部调用
dbms_lock.sleep(1);
END LOOP;
COMMIT;
END;

# 4. 处理措施

# 终止长事务
SQL> ALTER SYSTEM KILL SESSION ‘123,456’ IMMEDIATE;

System altered.

# 优化事务设计
# 原事务
BEGIN
FOR i IN 1..1000 LOOP
UPDATE fgedu.transactions SET status = ‘COMPLETED’ WHERE transaction_id = i;
— 模拟外部调用
dbms_lock.sleep(1);
END LOOP;
COMMIT;
END;
/

# 优化后事务
BEGIN
FOR i IN 1..1000 LOOP
UPDATE fgedu.transactions SET status = ‘COMPLETED’ WHERE transaction_id = i;
— 每100条提交一次
IF MOD(i, 100) = 0 THEN
COMMIT;
END IF;
END LOOP;
COMMIT;
END;
/

# 优化外部调用
# 将外部调用移到事务外
BEGIN
FOR i IN 1..1000 LOOP
UPDATE fgedu.transactions SET status = ‘COMPLETED’ WHERE transaction_id = i;
— 每100条提交一次
IF MOD(i, 100) = 0 THEN
COMMIT;
— 模拟外部调用
dbms_lock.sleep(1);
END IF;
END LOOP;
COMMIT;
END;
/

# 5. 验证结果

# 检查长事务是否已结束
SQL> SELECT s.sid, s.serial#, s.username, s.status, s.sql_id,
(SYSDATE – s.logon_time) * 24 * 60 * 60 AS session_age_seconds,
(SYSDATE – t.start_time) * 24 * 60 * 60 AS transaction_age_seconds
FROM v$session s
JOIN v$transaction t ON s.taddr = t.addr
WHERE (SYSDATE – t.start_time) * 24 * 60 > 1;

no rows selected

# 重新执行备份
RMAN> BACKUP DATABASE PLUS ARCHIVELOG;

Starting backup at 2026-04-01 10:00:00
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=123 device type=DISK
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00001 name=/yashanb/fgdata/fgedudb/system01.dbf
input datafile file number=00002 name=/yashanb/fgdata/fgedudb/sysaux01.dbf
input datafile file number=00003 name=/yashanb/fgdata/fgedudb/undotbs01.dbf
input datafile file number=00004 name=/yashanb/fgdata/fgedudb/users01.dbf
input datafile file number=00005 name=/yashanb/fgdata/fgedudb/fgedutbs01.dbf
channel ORA_DISK_1: starting piece 1 at 2026-04-01 10:00:00
channel ORA_DISK_1: finished piece 1 at 2026-04-01 10:05:00
piece handle=/yashanb/backup/fgedudb_full_20260401_12345.bkp tag=TAG20260401T100000 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:05:00
channel ORA_DISK_1: starting archived log backup set
channel ORA_DISK_1: specifying archived log(s) in backup set
input archived log thread=1 sequence=100
input archived log thread=1 sequence=101
input archived log thread=1 sequence=102
channel ORA_DISK_1: starting piece 1 at 2026-04-01 10:05:00
channel ORA_DISK_1: finished piece 1 at 2026-04-01 10:05:30
piece handle=/yashanb/backup/fgedudb_arch_20260401_12346.bkp tag=TAG20260401T100500 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:30
Finished backup at 2026-04-01 10:05:30

# 6. 预防措施

# 优化应用程序设计
– 避免在事务中进行外部调用
– 合理设置事务范围,及时提交或回滚
– 使用批量处理处理大量数据

# 加强监控和告警
– 配置长事务监控
– 设置合理的告警阈值
– 定期检查长事务

# 系统配置优化
– 增加undo表空间大小
– 设置合理的undo_retention参数
– 优化备份策略,避开业务高峰期

生产环境建议:长事务处理需要从设计、开发、运维等多个角度入手,采取综合措施预防和处理长事务。建议建立完善的长事务监控和处理机制,确保系统的稳定运行。from yashanDB视频:www.itpux.com

Part05-风哥经验总结与分享

5.1 YashanDB长事务处理经验总结

YashanDB长事务处理经验总结:

  • 预防为主:通过合理的设计和优化,预防长事务的发生
  • 监控及时:建立长事务监控机制,及时发现长事务
  • 处理高效:建立长事务处理流程,确保长事务能够被及时处理
  • 优化持续:针对长事务的原因,持续进行优化
  • 文档完善:记录长事务的处理过程和结果,为后续优化提供参考
  • 培训加强:加强开发人员和运维人员的培训,提高长事务处理能力
  • 工具使用:合理使用数据库工具,提高长事务处理效率
  • 应急演练:定期进行长事务处理的应急演练,确保应急方案的有效性
风哥提示:长事务是数据库性能优化中的重要问题,需要引起足够的重视。在设计和开发数据库应用时,应尽量避免长事务的发生,合理设计事务范围,确保事务能够快速提交或回滚。

5.2 YashanDB长事务处理检查清单

# YashanDB长事务处理检查清单
– [ ] 长事务监控机制是否建立
– [ ] 长事务告警阈值是否合理
– [ ] 长事务处理流程是否完善
– [ ] 应用程序中是否存在长事务风险
– [ ] SQL语句是否优化
– [ ] 事务设计是否合理
– [ ] 系统配置是否优化
– [ ] 长事务处理工具是否准备
– [ ] 长事务处理应急方案是否制定
– [ ] 长事务处理演练是否定期进行

# 长事务预防检查清单
– [ ] 事务范围是否合理
– [ ] SQL语句是否优化
– [ ] 批量操作是否合理
– [ ] 外部调用是否移出事务
– [ ] 事务隔离级别是否合适
– [ ] 提交频率是否合理
– [ ] 系统资源是否充足
– [ ] 监控和告警是否到位

5.3 YashanDB长事务处理工具推荐

YashanDB长事务处理常用工具:

  • 数据库视图:v$session、v$transaction、v$sql、v$active_session_history、dba_locks
  • 诊断工具:AWR、ASH、ADDM、SQL Tuning Advisor、Enterprise Manager
  • 操作系统工具:top、iostat、vmstat、netstat
  • 第三方工具:Toad、SQL Developer、Navicat、Prometheus + Grafana
  • 脚本工具:Shell脚本、Python脚本
  • 监控工具:Zabbix、Nagios、Datadog
持续改进:长事务处理是一个持续的过程,需要不断完善和优化。建议定期评估长事务处理机制的有效性,及时更新处理策略,确保系统的稳定运行。

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息