./dminit path=/data/dmdata CHARSET=1 PAGE_SIZE=32 EXTENT_SIZE=32 CASE_SENSITIVE=1 BLANK_PAD_MODE=1 SYSDBA_PWD=Dameng123! SYSAUDITOR_PWD=Dameng123!
数据库信息 03134284488-20260806-340608-20200
进行插入操作前 OUSHIN.DBF 128M arch大小1.1G
13:29开始插入数据
插入后 OUSHIN.DBF 1.5G arch大小6.0G 1024*6 表行数:1337万行
13:53开始update数据 用时11min14s
更新数据后 OUSHIN.DBF 1.7G arch大小7.0G 1024*7 表行数:1337万行
14:12开始delete数据
删除后 剩余数据1193万条 删除144万条 OUSHIN.DBF 1.7G arch大小9.0G 1024*9
测试前 无数据 OUSHIN.DBF 128M arch 0
15:13开始插入数据
插入数据后 OUSHIN.DBF 1.6G arch大小 1.0G 表行数:4282万行
15:40开始update数据
Update数据后 OUSHIN.DBF 1.6G arch大小 1.0G 表行数:4282万行
15:59开始delete数据
Delete数据后 OUSHIN.DBF 1.6G arch大小 3.0G 表行数:4282-195≈4086万行
此时再添加索引 用时16min
创建索引后不久OUSHIN.DBF 由1.6G→2.5G arch大小 3.0G不变
过一段时间后 OUSHIN.DBF 由2.5G→3.1G arch大小 3.0G→4.6G
看日志信息可以知道 2s完成创建 但是后续日志循环打印ALLOC-SESSION/FREE-SESSION
后台PURGE 做 undo 旧版本页清理
物理盘基本到上限 i/owait 50%左右 大部分时间等磁盘io
Top信息中显示dmserver占用82%内存 内核块设备io占用cpu高 表明在大量的读写磁盘,这里对应了purge刷undo旧版本页,做页回收工作
CLUSTERBTR聚簇索引重建(DDL 2s完成commit)
→ 产生海量undo历史版本页
→ 后台PURGE进程启动,反复ALLOC-SESSION/FREE-SESSION
→ 大量读旧版本页
→ 回收操作产生redo,持续写归档undo盘dm-1(大量小块写)
→ iowait升高,磁盘打满
→ dmserver本身CPU不高,压力全部在IO内核层(kblockd)
→ top看到kswapd0活跃,dmserver内存占用82.1%,buffer cache被大量旧页冲刷
有索引时
进行插入操作前 OUSHIN.DBF 128M arch大小1.1G
插入数据后 OUSHIN.DBF 1.5G arch大小6.0G 1024*6 表行数:1337万行
更新数据后 OUSHIN.DBF 1.7G arch大小7.0G 1024*7 表行数:1337万行
删除数据后 OUSHIN.DBF 1.7G arch大小9.0G 1024*9 表行数:1193万条
无索引时
进行测试前 无数据 OUSHIN.DBF 128M arch 0
插入数据后 OUSHIN.DBF 1.6G arch大小 1.0G 表行数:4282万行
更新数据后 OUSHIN.DBF 1.6G arch大小 1.0G 表行数:4282万行
删除数据后 OUSHIN.DBF 1.6G arch大小 3.0G 表行数:4086万行
创建索引后不久OUSHIN.DBF 由1.6G→2.5G arch大小 3.0G不变
过一段时间后 OUSHIN.DBF 由2.5G→3.1G arch大小 3.0G→4.6G
总结:
附件:
创建业务用户:
create tablespace "OUSHIN" datafile '/data/dmdata/DAMENG/OUSHIN01.DBF' size 128 autoextend on maxsize 102400;
create user "OUSHIN" identified by "Dameng123!" default tablespace "OUSHIN" default INDEX TABLESPACE "OUSHIN";
grant RESOURCE,PUBLIC,VTI,SOI,SVI to "OUSHIN";
-- 1. 创建表(使用 OUSHIN 表空间,参考金蝶ERP创建的普通表,名称TMP开头)
CREATE TABLE "OUSHIN"."TMP_AJE9IRYM4FEO0"
(
"FID" BIGINT,
"FVERSION" INT NOT NULL
)
STORAGE(ON "OUSHIN", CLUSTERBTR); -- 指定使用 OUSHIN 表空间
创建索引
CREATE OR REPLACE INDEX "OUSHIN"."IDX_TMP_AJE9IRYM4FEO0_FID"
ON "OUSHIN"."TMP_AJE9IRYM4FEO0"("FID" ASC)
STORAGE(ON "OUSHIN", CLUSTERBTR);
CREATE OR REPLACE INDEX "OUSHIN"."IDX_TMP_AJE9IRYM4FEO0_FVERSION"
ON "OUSHIN"."TMP_AJE9IRYM4FEO0"("FVERSION" ASC)
STORAGE(ON "OUSHIN", CLUSTERBTR)
删除索引
DROP INDEX OUSHIN.IDX_TMP_AJE9IRYM4FEO0_FID;
DROP INDEX OUSHIN.IDX_TMP_AJE9IRYM4FEO0_FVERSION;
测试前后记录差值
select count(*) as A_TABLE_ROWS from OUSHIN.TMP_AJE9IRYM4FEO0;
-------------------------------------------------insert-------------------------------------
DECLARE
V_START_TIME TIMESTAMP;
V_BATCH_SIZE INT := 10000;
V_TOTAL INT := 0;
BEGIN
V_START_TIME := SYSDATE;
WHILE SYSDATE < V_START_TIME + INTERVAL '10' MINUTE LOOP
INSERT INTO OUSHIN.TMP_AJE9IRYM4FEO0(FID, FVERSION)
SELECT
DBMS_RANDOM.VALUE(1, 9999999999), -- 随机BIGINT
TRUNC(DBMS_RANDOM.VALUE(1, 1000))
FROM DUAL
CONNECT BY ROWNUM <= V_BATCH_SIZE;
V_TOTAL := V_TOTAL + V_BATCH_SIZE;
IF MOD(V_TOTAL, 100000) = 0 THEN
COMMIT;
PRINT '已插入: ' || V_TOTAL || ' 行,已运行: ' || (SYSDATE - V_START_TIME) || ' 秒';
END IF;
END LOOP;
COMMIT;
PRINT '========== 完成 ==========';
PRINT '总插入行数: ' || V_TOTAL;
PRINT '总耗时: ' || (SYSDATE - V_START_TIME) || ' 秒';
END;
/
-------------------------------------------------update-------------------------------------
DECLARE
V_START_TIME TIMESTAMP;
V_BATCH_SIZE INT := 10000;
V_TOTAL INT := 0;
BEGIN
V_START_TIME := SYSDATE;
WHILE SYSDATE < V_START_TIME + INTERVAL '10' MINUTE LOOP
--批量更新随机行
UPDATE OUSHIN.TMP_AJE9IRYM4FEO0
SET FVERSION = TRUNC(DBMS_RANDOM.VALUE(1,1000))
WHERE FID IN (
SELECT FID FROM OUSHIN.TMP_AJE9IRYM4FEO0
WHERE FID IS NOT NULL
ORDER BY DBMS_RANDOM.VALUE
FETCH FIRST V_BATCH_SIZE ROWS ONLY
);
V_TOTAL := V_TOTAL + V_BATCH_SIZE;
IF MOD(V_TOTAL, 100000) = 0 THEN
COMMIT;
PRINT 'UPDATE已处理: ' || V_TOTAL || ' 行,已运行: ' || (SYSDATE - V_START_TIME) || ' 秒';
END IF;
END LOOP;
COMMIT;
PRINT '========== UPDATE压测完成 ==========';
PRINT 'UPDATE总处理行数: ' || V_TOTAL;
PRINT 'UPDATE总耗时: ' || (SYSDATE - V_START_TIME) || ' 秒';
END;
/
-------------------------------------------------delete-------------------------------------
DECLARE
V_BATCH_SIZE INT := 10000;
V_AFFECTED INT; --本次实际删除行数
V_TOTAL INT := 0; --累计真实删除行数
V_START_TIME TIMESTAMP; --改成TIMESTAMP,支持interval
BEGIN
V_START_TIME := SYSTIMESTAMP;
WHILE SYSTIMESTAMP < V_START_TIME + INTERVAL '10' MINUTE LOOP
-- 达梦FETCH FIRST不支持变量,改用rownum取前N行
DELETE FROM OUSHIN.TMP_AJE9IRYM4FEO0
WHERE FID IN (
SELECT FID
FROM (
SELECT FID
FROM OUSHIN.TMP_AJE9IRYM4FEO0
WHERE FID IS NOT NULL
) t
WHERE ROWNUM <= V_BATCH_SIZE
);
V_AFFECTED := SQL%ROWCOUNT; --获取本次真实删除行数
EXIT WHEN V_AFFECTED = 0; --表已经删完,直接退出循环,避免空跑
V_TOTAL := V_TOTAL + V_AFFECTED;
IF MOD(V_TOTAL, 100000) = 0 THEN
COMMIT;
PRINT 'DELETE已处理: ' || V_TOTAL || ' 行,已运行: ' || TO_CHAR(EXTRACT(SECOND FROM(SYSTIMESTAMP - V_START_TIME)),'999999.999') || ' 秒';
END IF;
END LOOP;
COMMIT;
PRINT '========== DELETE压测完成 ==========';
PRINT 'DELETE总处理行数: ' || V_TOTAL;
PRINT 'DELETE总耗时(秒): ' || TO_CHAR(EXTRACT(SECOND FROM(SYSTIMESTAMP - V_START_TIME)),'999999.999');
END;
/
文章
阅读量
获赞
