1 服务器内存管理
1.1 、内存池
共享内存池
memory_target:指定单个共享内存池的目标大小
memory_pool: 指定单个共享内存池的初始大小
memory_extent_size:提定单个共享内存池的增量大小
memory_N_pool :指定多个共享内存池
备用内存池
1.2 、缓冲区
(1) 数据缓冲区:
normal(buffer)一般缓冲区,存储普通数据页,正常的淘汰机制 ,LRU 最近未使用原则淘汰,
Keep:常驻内存,不会轻易淘汰出去,一般用于存储热点数据,
fast:快速访问数据缓冲区
Recycle:临时缓冲区
MULTI_PAGE_GET_NUM=1
一条“自由链”重来没有使用过的数据页, “LRU”链 . ”脏“链
(2)日志缓冲区:RLOG_BUF_SIZE page 2N 次方
(3)字典缓冲区:DICT_BUF_SIZE
(4)Sql 缓冲区: cache_pool_size SELECT * FROM test.emp;
SELECT * FROM TEST.EMP;
3 、运行时的内存池:会话内存池,虚拟机内存池
4 、排序区和哈希区
其中共享内存池,备用内存池,字典缓冲区,sql 缓冲区,排序区和哈希区,会话内存和虚拟机内池池都采用内存池结构来实现管理。数据缓冲区, 日志缓冲区使用其他的内存管理方式。
按结构分类
内存池,堆及混合结构三种。内存池分为普通内存池和运行时的内存池。
内存使用流程
达梦数据库服务启动时,向操作系统申请6块独立的内存区, 日志缓冲区,字典缓冲区,共享内存池,备用内存池,sql 缓冲区)
如果有会话连接,则会去建立相关的内存池 池,虚拟机内存池等)会话结束后,相关内存池回收。
服务器关闭,OS 回收所有的内存。
1 、数据缓冲区keep,recycle,normal,fast).服务器启动后,向操作系统 申请四块大小固定的内存做为四个分区,服务器关闭前向操作系统归 还内存。数据缓冲区不会拓展。
数据缓冲区四种类型:
Normal : 普通数据页,缓冲区满进行淘汰。
Fast:数据页,回滚页,常驻缓冲区
Recycle: 临时表数据页,正常淘汰
Keep:普通数据页,很少淘汰
5、日志缓冲区,创建时从操作系统分配内存,服务器关闭前向操作 系统归还,日志缓冲区拓展时直接向操作系统申请。
6、运行时内存池:在需要使用的时候被创建,使用完毕立即销毁, (会话内存池,虚拟机内存池,排序区和哈希区) 。
1.2 后台的进程和线程
达梦是单进程多线程的,每一个实例只有一个进程v$process;
V$threads;
监听线程:在服务端口上进行循环监听,一旦有来自客户的连接请求, 监听线程被唤醒并生成一个会话申请任务。
工作线程:DM 服务器的核心线程
任务线程
IO 线程:最为耗时的操作之一。
调度线程:日志flush 线程
MAL 系统相关线程
V$THREADS:记录当前系统中活动线程的信息
V$wthrd_history :记录自系统启动以来,所有活动过的线程的要历史信息。
V$PROCESS :记录服务器进程信息。
V$SESSIONS:
1.3 sql 执行的过程
SELECT * FROM v$sessions WHERE state =’ACTIVE’;
SELECT * FROM v$sessions WHERE state =’ACTIVE’;
1 、语法分析(字典缓冲区)
2 、语义分析(字典缓冲区)
3 、权限判断(字典缓冲区)
4 、是否存在执行计划(sql 缓冲区,buffer)
5 、执行SQL:结果缓冲到sql 缓冲区(sql 缓冲区,排序区,哈希区, buffer)
1.4 sql 优化27号上午 2:30
Java Dmlog_dm7_5.0.jar
-----开启sql 日志SVR_LOG
SP_SET_PARA_VALUES(1,’SVR_LOG’,1);
关闭sql 日志
Sp_set_para_values(1,’SVR_LOG’,0);
使用sql 日志的流程:
---设置SQL 过滤规则,只记录必要的SQL ,生产环境不要设成1
-- 2 只记录DML 语句3 只记录DDL 语句22 记录绑定参数的语句
-- 25 记录SQL 语句和它的执行时间28 记录SQL 语句绑定的参数信息
SELECT SF_SET_SYSTEM_PARA_VALUE('SQL_TRACE_MASK','2:3:22:25:28', 0,1);
-- 同步日志会严重影响系统效率,生产环境必须设置为异步日志 SELECT SF_SET_SYSTEM_PARA_VALUE('SVR_LOG_ASYNC_FLUSH',1,0,1); --下面这个语句设置只记录执行时间超过200ms 的语句
SELECT SF_SET_SYSTEM_PARA_VALUE('SVR_LOG_MIN_EXEC_TIME',200, 0,1);
--下面的语句查看设置是否生效
SELECT * FROM V$DM_INI WHERE para_name='SVR_LOG_ASYNC_FLUSH'; SELECT * FROM V$DM_INI WHERE para_name='SQL_TRACE_MASK';
SELECT * FROM V$DM_INI WHERE para_name='SVR_LOG_MIN_EXEC_TIME';
案例1:
分析及优化:
序号 | 分析 | 优化方法 | 优化前平均执行时间 | 优化后平均执行时间 | |
SQL1 | 走主键更新,需要二次定位 | 改为聚集主键,消除二次定位的代价 | 100ms | 10ms | |
SQL2 | 序列缓存为 发小了一些 | 将序列缓存调到 | 5ms | 1ms | |
SQL3 | 频繁调用系统函数sysdate 代价很大 | 一个事务里只取一次sysdate,存入变量,后 面引用变量。但是应用修改起来很麻烦,暂时 不改。 | 1ms | ||
SQL4 | 走普通索引,需要二次定位 | 改为覆盖索引,消除二次定位的代价 | 200ms | 50ms | |
效果:优化后系统比较稳定,IO,CPU 降到原来的1/3,瘫痪的次数大大减少了。
达梦数据库配置了执行计划重用的参数:use_pln_pool;
0 :禁止执行计划的重用,
1 :启用执行计划的重用功能。
2 :对不包含显示参数的语句进行常量参数优化。
3 :即使包含显示参数的语句,也进行常量参数优化。
Sql 性能分析功具:ET 是 DM自带的分析工具,能统计SQL 每个操作符的时间花费,从而定位 到有性能问题的操作,指导用户去优化。
dm_ini参数ENABLE_MONITOR=1, MONITOR_SQL_EXEC=1 时,ET才能使用
select para_name,para_value from v$dm_ini where para_name in('ENABLE_MONITOR','MONITOR_SQL_EXEC');
执行语句开启ET -- SQL性能分析工具
SP_SET_PARA_VALUE(1,'ENABLE_MONITOR',1);
SP_SET_PARA_VALUE(1,'MONITOR_SQL_EXEC',1);
CALL ET(390009);
SQL 编写规则:
1 、统一编写风格
SELECT * FROM test;
SELECT * FROM TEST;
SETECT * FROM test;
2 、使用绑定变量
SELECT * FROM test WHERE id=?
SELECT * FROM test WHERE id=6
3 、避免排序sort 索引来代替
4 、减少表的重复扫描。
5 、用exist 替代in
SELECT * FROM test.t1 WHERE id in (1,3,5,7,8,9);
SELECT * FROM test.t1 WHERE id exist (1,3,5,7,8,9);
6 、避免普通索引列上有计算。
SELECT * FROM tab1 WHERE c-1=123;
SELECT * FROM tab1 WHERE c=123+1;
7 、避免隐式转换
Bri (date) bri='1990-01-01';
Bri = to_date('1990-01-01','yyyy-mm-dd’');
To_date(bri)= to_date
8 、尽量避免使用SELECT *
9 、多表连接的时候,必须使用别名来引用列,记录数大于1000 万时,关联的大表尽量不超过4 个。
10 、嵌套循环连接查询需要注意地方:
选择小表作为驱动表,统计信息尽量准确,保证优化器选对驱动表。适当使用索引。
11 、hash join 特点
Hash 连接比较消耗内存
Hj_buf_golbal_size hj_buf_size hj_blk_size.
12 、对于大批量dml 操作分段提交, 防止大事务。
13 、尽量使用缓存。
14 、Delete update 加WHERE。
SELECT ename FROM emp e WHERE exists (SELECT 'x' FROM dept WHERE dept_no=e.dept_no and dept_cat ='A');
SELECT ename FROM dept d, emp e WHERE e.dept_no=d.dept_no and dept_cat='A';
1.5 awr 报告
SYS.WRM$_WR_CONTROL 记录快照的相关控制信息。
Sys.wrm$_snapshot 记录快照的相关信息
1 、初始化awr 快照包
创建或删除DBMS_WORKLOAD_REPOSTORY 系统包,为1 的时候表示创建。 为 0 表示删除该系统包。
SELECT SF_CHECK_AWR_SYS;
SP_INIT_AWR_SYS(1); 一定要执行这个语句不然下面执行报错
2 、设置时间
SQL> call dbms_workload_repository.awr_set_interval(10);
3 、手动生成快照
SQL> call dbms_workload_repository.create_snapshot();
4 、查询快照
SQL> SELECT * FROM sys.wrm$_snapshot;
查看行数,至少2行才能出报告,没有就多执行3(手动生成快照)几次就好了
5 、生成awr 报告
SQL> call sys.awr_report_html(1,3,'/dm8','awr1.html');
数据库负载:db_time/(elapsed *cpus) >80% , 说明存在性能问题,我们需要分析top 事件,或sql order by elapse time
NON_parse cpu:sql 实际运行时间/(sql 实际运行时间+sql 解析时间) 。
太低,表示sql 解析消耗时间过多。
Execute to parse:语句执行与分析比例。如果sql 重用率高,则这个比例高。 相关的动态视图。
BUFFER HIT 90%
等待事件:v$system_event, v$session_event, v$event_name, v$sessions; 内存:v$buffer, v$bufferpool, v$pool , V$mem_pool;
锁:v$lock;