SQL Server 内存管理
windows memory: Memory: Cache Bytes 是系统的working set, 也就是系统使用的物理内存数目。 可以观察Windows用了多少物理内存。
1. System Cache Resident Bytes
2. System Driver Resident Bytes
3. System Code Resident Bytes
4. Pool Paged Resident Bytes
SQL Server 动态管理内存:
SQL Server 是通过以下的API去感知windows是否有内存压力:
APIQueryMemoryResourceNotification -》 windows memory -》 decrease target server memory.
Total server memory : SQL Server启动账户拥有 Lock pages in memory 权限, 锁定内存,避免windows抢夺内存
Target server memory: SQL在启动时候, 比较AWE, max server memory, physical memory 三者选一个最小的值作为Target server memory.
comparison |
Result |
Remark |
Total < target |
Windows has enough memory, SQL can allocate new memory for new data |
Total is increasing |
Total = target |
SQL used all of memory, SQL don’t allocate new memory for new data |
SQL clean up memory for new data, such as Lazy writer |
Total > target |
Windows has memory pressure, SQL decrease Target |
SQL clean up memory for new data, such as Lazy writer to release buffer pool and cached plan |
SQL server 内存管理概念: DBCC memorystatus -- 查看内存使用情况
1. Reserved memory:
2. Committed memory: = Physical memory + Page file = Shared memory + Private Bytes
3. Shared memory:
4. Private Bytes:
5. Working Set: = shared memory + Private Bytes - Page file
6. Page Fault(soft/hard)
32位SQL:
memToLeave: 256MB+256thread*521KB=384MB (SQL 启动的时候就计算好了,不能变大): extended stored procedure, third party dirver, and linked server : 启动参数 -g512 = 512MB+256thread*521KB
BufferPool = 2G-384MB=1664MB (包括 database cache + stolen memory)
AWE开启以后, 只能给先reserve再commit的部分使用,即只能给database cache来扩展使用(Physical memory-2GB就是AWE扩展后database cache所能用的内存数量),stolen memory只能用1664MB里的内存。
SQL内存使用情况分析:
1. SQL性能计数器:
memory manager:
Total server memory,
target server memory,
Optimizer memory
SQL cache memory
Lock memory
Connection memory
Granted workspace memory: hash, sort, bulk-insert, create index...
Memory grants pending: 等待工作空间内存授权的进程总数, 不等于0, 意味着比较严重的内存瓶颈
Buffer manager:
Buffer Cache Hit Ratio: 应该>99%, 如果<95%, 通常就是内存不足的问题
Checkpoint pages/sec: 这个和内存压力没有关系,和用户的行为有关。用户做很多insert/update/delete, 这个值就会很大,脏数据多。
database pages: 就是 database cache
free pages:
Lazy writes/sec: 如果SQL 内存压力不大,不会经常触发lazy writer。 如果经常触发, 那么就应该是有内存的瓶颈
page life expectancy: 页不被引用,将在缓冲池中停留的秒数。只有Lazy writer 被触发, Page life expectancy 才会突然下降。如果总是高高低低的, 应该是有内存压力
page reads/sec: 这个值正常情况下应该很低。 如果比较高, 一般page life expectancy 会下降, Lazy writes/sec 会上升。
stolen pages: 所有非database pages, 包括执行计划缓存。
内存DMV:sys.dm_os_memory_clerk
select type,
sum(virtual_memory_reserved_kb) as [vm reserved],
sum(virtual_memory_committed_kb) as [vm committed],
sum(awe_allocated_kb) as [AWE allocated],
sum(shared_memory_reserved_kb) as [SM reserved],
sum(shared_memory_committed_kb) as [SM committed],
sum(multi_pages_kb) as [Multipage allocator],
sum(single_pages_kb) as [Singlepage allocator]
from sys.dm_os_memory_clerks
group by type
order by type
内存中的数据页面由哪些表格组成,各占多少: sys.dm_os_buffer_descriptors
dbcc dropcleanbuffers --clean up data buffer
go
declare @name varchar(100)
declare @cmd varchar(5000)
declare c1 cursor for select name from sys.sysdatabases
open c1
fetch next from c1 into @name
while @@FETCH_STATUS=0
begin
print @name
set @cmd= 'select b.database_id, db=db_name(b.database_id), object_name(p.object_id), p.index_id, buffer_count_kb=count(*)*8 from ' +@name+'.sys.allocation_units a, '+@name+'.sys.dm_os_buffer_descriptors b,'+@name +'.sys.partitions p where a.allocation_unit_id=b.allocation_unit_id and a.container_id=p.hobt_id ' +' and b.database_id=db_id('''+@name+''')' +' group by b.database_id, p.object_id, p.index_id ' +' order by b.database_id, buffer_count_kb desc '
print @cmd
exec(@cmd)
fetch next from c1 into @name
end
close c1
deallocate c1
go
执行计划都缓存了些什么? 哪些比较占内存?
select objtype, sum(size_in_bytes) as sum_size_in_bytes, count(bucketid) as cache_counts
from sys.dm_exec_cached_plans
group by objtype
select usecounts,refcounts, size_in_bytes, cacheobjtype, objtype, text
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(plan_handle)
order by objtype desc;
go
-----------------华丽的分割线: 下面开始分析 数据页面(database page), buffer pool 里的stolen, multi-page 这三部分------------------------------------
数据缓冲区压力分析:
Lazy writes/sec 高
Page life expectancy 低
Page reads/sec 高: 正常这个值应该接近0, 指从数据文件读取的数据量
Stolen pages 降低
sys.sysprocesses 中出现一些连接等待I/O完成的现象: PAGEIOLATCH_SH
使用DMV分析启动以来做read最多的语句:
--按照物理读的页面数排序,前50名:
select top 50
qs.total_physical_reads, qs.execution_count,
qs.total_physical_reads / qs.execution_count as [avg IO],
substring(qt.text, qs.statement_start_offset/2,
(case when qs.statement_end_offset = -1 then len(convert(nvarchar(max), qt.text)) * 2
else qs.statement_end_offset end - qs.statement_start_offset)/2) as query_text,
qt.dbid, dbname=db_name(qt.dbid),
qt.objectid, qs.sql_handle, qs.plan_handle
from sys.dm_exec_query_stats qs
cross apply sys.dm_exec_sql_text(qs.sql_handle) as qt
order by qs.total_physical_reads desc
--按照逻辑读的页面数排序,前50名
select top 50
qs.total_logical_reads, qs.execution_count,
qs.total_logical_reads / qs.execution_count as [avg IO],
substring(qt.text, qs.statement_start_offset/2,
(case when qs.statement_end_offset = -1 then len(convert(nvarchar(max), qt.text)) * 2
else qs.statement_end_offset end - qs.statement_start_offset)/2) as query_text,
qt.dbid, dbname=db_name(qt.dbid),
qt.objectid, qs.sql_handle, qs.plan_handle
from sys.dm_exec_query_stats qs
cross apply sys.dm_exec_sql_text(qs.sql_handle) as qt
order by qs.total_logical_reads desc
--使用trace 文件分析做read最多的语句
select * into sample
from fn_trace_gettable('c:\sample.trc',default)
where eventclass in (10, 12) -- 10: RPC completed 12: SQL batch completed
select top 1000 textdata, databaseid, hostname, applicationname, loginname, spid
starttime, endtime,duration,reads,writes,cpu
from sample
order by reads desc
--使用ReadTrace工具分析trace文件,找出使用大量系统资源的语句
使用方法见稍后发出。。。
Stolen Memory缓存压力分析:
Stolen memory 凡是以8K为分配单位的,保存在buffer pool里。 大于8K的,保存在MemToLeave里。
缓存: 执行计划,用户安全上下文,连接的数据结构和输入/输出缓冲区
没有缓存: 语义分析,优化,排序,Hash,计算
Stolen memory 在不同的SQL版本,最大的限制是不同的,见下表:
表征与解决方法:查看 sys.sysprocesses 里面的连接等待waittype字段不等于0x0000: (可以手动 DBCC FREEPROCCACHE)
1. CMEMTHREAD (0x00B9)
2. SOS_RESERVEDMEMBLOCKLIST (0x007B)
3. RESOURCE_SEMAPHORE_QUERY_COMPILE(0x011A)
SQL Server 内存管理的更多相关文章
- 人人都是 DBA(IV)SQL Server 内存管理
SQL Server 的内存管理是一个庞大的主题,涉及特别多的概念和技术,例如常见的 Plan Cache.Buffer Pool.Memory Clerks 等.本文仅是管中窥豹,描述常见的内存管理 ...
- SQL Server 内存管理在64位时代的改变
64位机上 地址空间比以前大了去了.它引起的改变多了去了 1.MemToLeave这个词不存在了.因为SQL Server以不再做这种预留空间的事了,也就是说multiple page 想用多少就用 ...
- Sql Server 内存相关计数器以及内存压力诊断
在数据库服务器中,内存是数据库对外提供服务最重要的资源之一, 不仅仅是Sql Server,包括其他数据库,比如Oracle,MySQL等,都是一类非常喜欢内存的应用. 在Sql Server服务器中 ...
- sql server 内存初探
一. 前言 对于sql server 这个产品来说,内存这块是最重要的一个资源, 当我们新建一个会话,相同的sql语句查询第二次查询时间往往会比第一次快,特别是在sql统计或大量查询数据输出时,会有这 ...
- (1)SQL Server内存浅探
1.前言 对于数据库引擎来说,内存是一个性能提升的重要解决手段.把数据缓存起来,可以避免在查询或更新数据时花费多余的时间,而这时间通常是从磁盘获取数据时用来等待磁盘寻址的.把执行计划缓存起来,可以避免 ...
- SQL SERVER 内存学习系列(二)-DMV查看内存信息
内存管理在SQL Server中有一个三级结构.底部是内存节点,这是最低级的分配器,用于SQL Server的内存.第二个层次是由内存Clerk组成,这是用来访问内存节点和缓存存储,缓存存储则用于缓存 ...
- SQL Server内存理解的误区
SQL Server内存理解 内存的读写速度要远远大于磁盘,对于数据库而言,会充分利用内存的这种优势,将数据尽可能多地从磁盘缓存到内存中,从而使数据库可以直接从内存中读写数据,减少对机械磁盘的IO请求 ...
- SQL SERVER 内存分配及常见内存问题 DMV查询
内存动态管理视图(DMV): 从sys.dm_os_memory_clerks开始. SELECT [type] , SUM(virtual_memory_reserved_kb) AS [VM R ...
- SQL SERVER 内存分配及常见内存问题 简介
一.问题: 1.SQL Server 所占用内存数量从启动以后就不断地增加: 首先,作为成熟的产品,内存溢出的机会微乎其微.对此要了解SQL SERVER与windows是如何协调.共享内存.并且SQ ...
随机推荐
- 查询Table name, Column name, 拼接执行sql文本, 游标, 存储过程, 临时表
018_Proc_UpdateTranslations.sql: SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO if (exists (select ...
- 【JMeter】JMeter使用plugins插件进行服务器性能监控
性能测试时,我们的关注点有两部分 1 服务本身:并发 响应时间 QPS 2 服务器的资源使用情况:cpu memory I/O disk等 JMeter的plugins插件可以实现对"二&q ...
- 黑盒测试用例设计方法&理论结合实际 -> 场景法
一概念 现在的软件几乎都是用事件触发来控制流程的,事件触发时的情景便形成了场景,而同一事件不同的触发顺序和处理结果就形成事件流.这种在软件设计方面的思想也可以引入到软件测试中,可以比较生动地描绘出事件 ...
- unity3d实现序列帧动画
首先准备一个序列帧图片如下的AngryBird: 场景中随便创建一个物体,这里以Cube为例 将图片拖放到Cube上,这样会在Cube的6各面都有3个bird,为了美观显示一个鸟,我们调整材质的Til ...
- ajax跨域解决方案(服务端仅限java)
楼主前端知识菜鸟,高手勿喷,在此记录工作中遇到的问题及解决方案,大神请滤过 方法1.jsonp(js客户端ajax请求参数方式设置) 方法2.服务端接口设置: HttpServletResponse ...
- Java常用知识点
1. java不支持默认参数,需要用重载来实现 2. java中要比较字符串是否相等,不能用等号,要用equals函数来比较内容 3. 尽量避免使用try catch来捕获异常,可以使用if语句判断以 ...
- [Objective-c 基础 - 1.3] OC带返回值的类方法
/* 计算器类 1>返回π 2>计算两个整数的平方 3>计算两个整数的和 */ #import <Foundation/Foundation.h> @interface ...
- 在高版本SDK中打开现存低版本SDK工程
直接打开低版本SDK工程会出现错误提示:“Unable to resolve target 'android-xx” 解决方法: 1.将project.properties文件中的“target=an ...
- function和感叹号,运算符号的转化
1.下面的程序经过运算之后,a为true,这个很好理解,但是函数怎么会运行呢? var a = !function(){ alert('message'); }(); console.log(a); ...
- SQLite使用教程4 创建数据库
http://www.runoob.com/sqlite/sqlite-create-database.html SQLite 创建数据库 SQLite 的 sqlite3 命令被用来创建新的 SQL ...