爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      用好HugePage,告别Linux性能故障

      首页 知识中心 数据库 文章详情页

      用好HugePage,告别Linux性能故障

      2023-05-18 09:34:04 阅读次数:111

      Linux,oracle

      用好HugePage,告别Linux性能故障
       
      第一章 用好HugePage,告别Linux性能故障

      DBAplus社群 | 2016-04-14 20:31

      1概述

      Oracle发展这么多年,提供了多种的内存管理方式,从最早SGA、PGA手工管理,到9I版本出现的PGA的自动管理,到10G版本出现的SGA自动管理(ASMM),再到11G版本出现的memory自动管理(AMM),Oracle基本是在朝着智能化、傻瓜化、自动化的方向稳步前进着,对于初学Oracle的DBA来说,看到这些不同的内存管理方式一定心里有着不同程度的疑惑,例如:

      Oracle有这么多内存分配的管理方式,我该使用哪一种?是使用11G版本推出的AMM管理方式,还是使用10G版本出现的ASMM管理方式?或者干脆使用最旧的手工方式管理内存?

      我该为我的实例SGA,PGA分别设置多大呢?

      我该为buffer cache,shared pool分配多大的内存空间?

      什么情况下我该使用大页?为什么大页这个词最近几年这么容易听到?

      有没有一些简单粗暴的算法来搞定这一切?

      写这篇文章的初衷也来源于上面这些非常正常的疑问,如果这篇文章能给有这些疑惑的DBA朋友一些指导和帮助,那肉丝我也就真的功莫大焉了。

      2Memory构成

      在一个运行着Oracle数据库的专用服务器上,内存基本上被以下内容所占用:

      Kernel Memory

      OS Page Table

      文件系统Cache

      SGA

      PGA

      Oracle进程

      其他进程(RMAN,非Oracle的进程等等)

      用好HugePage,告别Linux性能故障

      严格来说OS Page Table也算是Kernel Memory部分的内容,由于本文后面会重点讲大页的内容,因此把OS Page Table这部分在图中独立了出来,以引起读者注意。必须要强调,Oracle不应该使用掉主机上的所有内存,过量的内存分配会诱发操作系统SWAP的产生,导致Oracle性能严重降低,在RAC环境下,内存不足还非常容易导致RAC节点的驱逐。对于Oracle两大块内存:SGA和PGA,DBA一定要仔细根据系统特点、业务使用特点做好规划和设计,以防出现OS内存不够用的情况。

      3内存自动化发展历程

      我们首先了解一下Oracle内存发展的历程,基本上Oracle的内存管理在版本的演进过程中沿着越来越智能化、自动化、傻瓜化的方向前进。接触过MYSQL等数据库的DBA朋友应该比较清楚,这些数据库基本上都还需要DBA去决定每个内存组件的大小,而Oracle已经从9I版本开始就迈向智能化、自动化的过程了。下图是Oracle内存管理的一个演进图:

      用好HugePage,告别Linux性能故障

      4PGA 自动管理

      Oracle是多进程的架构,这点区别于MYSQL,MYSQL是单进程多线程的架构,Oracle会为每一个用户连接创建一个独立的操作系统进程来为用户提供服务,这个进程叫做服务器进程或者影子进程,它像是用户的一个代理,来操作数据文件或者SGA内存,由于服务器进程的代码是Oracle公司开发的,所以Oracle公司完全相信这些进程或代码是安全的,因此这些进程可以直接操作数据文件和SGA内存,这些进程接受用户进程发送的指令,并完成相关的操作,并根据需要来给用户进程返回结果。

      由于服务器进程是操作系统上的一个进程,因此它本身需要占用一些操作系统内存,除此之外,进程在对数据进行读取、排序、hash过程中,也会占用一定量的内存,在Oracle 9I版本之前,对于服务器进程的内存管理是由一些参数去控制的,以下参数代表每一个服务器进程可以使用的不同区域的内存大小(都是进程的私有内存区域):

      SORT_AREA_SIZE

      HASH_AREA_SIZE

      BITMAP_MERGE_AREA_SIZE

      CREATE_BITMAP_AREA_SIZE

      例如,SORT_AREA_SIZE控制了每一个进程可用的排序区大小,HASH_AREA_SIZE参数控制了每一个进程可用的hash区大小,这些参数都有默认值,但是默认值是否合适,需要打上一个大大的问号,因为不同的任务对于PGA内存的不同区域有不同的要求,例如,如果是做排序操作,就对排序区内存要求较大,而对hash区没任何的要求。当然如果默认值不合适,DBA可以手工调整这些区域的大小。

      Oracle 9I版本出现了PGA的自动管理,不再需要像9I之前版本需要设置一系列参数来控制PGA的使用,只需要设置PGA_AGGREGATE_TARGET为一个值,就可以控制所有的服务器进程的PGA使用量,至于每个服务器进程使用了多少排序区,hash区,都交给Oracle去控制。

      一般情况下对于PGA的大量使用有如下几种操作:

      hash 对于hash join操作,hash桶所占用的内存就在进程的私有PGA内存中,而不是在共享内存SGA中,如果使用PGA手工管理的话,可以通过HASH_AREA_SIZE参数来动态调整会话进行hash操作能够使用的内存量。

      sort 对于排序操作,例如查询语句里的order by、创建索引的排序操作等占用的内存也在PGA中,如果使用PGA手工管理,可以通过SORT_AREA_SIZE参数动态调整会话排序操作可以使用的内存量。

      parallel 并行操作简直可以说是PGA内存的杀手,每一个并行进程都能使用到最多2G的PGA内存,当然Oracle会确保所有的并行slave使用的PGA内存不能超过PGA_AGGREGATE_TARGET的一半。

      现在Oracle的版本已经出到了12C,PGA的自动管理已经发展了很多个年头,如果是个人,也应该是一个非常成熟的小伙子了,甚至是位大叔了,绝大部分数据库操作完全没必要再去手工调整PGA的一些参数。

      不过,我们依然能从互联网上、论坛上看到有很多DBA对这种手工调整PGA的技术崇拜有加(我以前也是),确实在一些情况下,通过手工调整PGA的相关内存区,可以达到加速排序等一些操作的目的,但是如果需要操作的数据量非常的大,那这种调整往往是费时费力,甚至是徒劳的,因为对于一个进程的私有PGA内存来说,像sort,hash等P区域的内存分配是有限制的,现在11GR2的版本对于每个进程的PGA内存最大限制默认是2个G,且排序区可以使用的只有1个G,如果你的排序等操作需要的内存远远不止1,2个G,那么这种优化就非常的徒劳,甚至还可能变慢(肉丝亲身遭遇过变慢的案例)。

      是否使用PGA自动管理由参数WORKAREA_SIZE_POLICY控制,它的值可以为auto和manual,顾名思义,auto为PGA自动管理,manual为PGA手工管理,回到9I之前的使用方式。

      这里肉丝提供几个大家可能会感兴趣的隐含参数,比如我上面提到了每个进程最大能使用的PGA不能超过2个G,通过修改隐含参数可以突破这个限制。>肉丝在这里警戒各位,这些参数如果要在生产环境使用,请在你的数据库版本下做好测试(包括相同的OS及版本)。

      以下为11GR2版本的情况,其他版本并未做测试:

      _PGA_MAX_SIZE 每个进程的PGA的最大内存大小。默认值为:2147483648,2个G,单位为B。

      _SMM_MAX_SIZE 每个进程的工作区的大小,默认值为1/2 _PGA_MAX_SIZE,1048576 ,单位KB,1GB,排序区、hash区都属于工作区的范围。64位系统下真实使用的排序区内存不能超过4GB。

      _SMM_PX_MAX_SIZE 所有并行查询的SLAVE进程能够用到的PGA总量。默认值为 1/2 pga_aggregate_target,单位为KB,RAC环境下,每个节点都可以用到这么多内存。

      以上全部为动态参数,可以在session/system级别来在线修改。

      用好HugePage,告别Linux性能故障

      上面的参数调整后,一定要设置对应的pga_aggregate_target,否则以上调整可能会不起作用,建议设置为修改后的_SMM_PX_MAX_SIZE的值的两倍。

      默认情况下,每个进程使用的排序区不能超过1G。由参数_SMM_MAX_SIZE(单位KB)控制,默认为_PGA_MAX_SIZE(单位B)的一半。例如,并行度20创建索引,总共可以使用的排序区大小为20*1G=20G,但是同时还受参数_SMM_PX_MAX_SIZE的控制,所有的slave占用的内存不能超过_SMM_PX_MAX_SIZE的值(单位为KB),默认为pga_aggregate_target的一半。同时64位系统下,每个进程可以使用的排序空间不能超过4个G。所以即使把_SMM_MAX_SIZE调整大于4个G也没有用。_SMM_PX_MAX_SIZE,所有并行查询的SLAVE进程能够用到的PGA总量。每个RAC 节点都可以用到这么多,限制的是本节点所有并行slave能够消耗的PGA。

      如何为PGA_AGGREGATE_TARGET设置一个合理的值?

      PGA_AGGREGATE_TARGET的设定经常是一个摸索的过程,这里给出官方的一个分配指导原则

      用好HugePage,告别Linux性能故障

      上面公式中的TOTAL_MEM * 80%代表着Oracle可以使用的所有内存为操作系统的80%,再根据不同类型业务的特点,OLTP系统,可以在此基础上分配20%的内存给PGA,DSS分析型系统,可以给出剩余内存的50%。这个只是一个指导的意见,具体情况要具体分析。例如,你的OLTP系统上有成千上万个连接,那么你可以粗略的按照每个进程占用10M的内存来大体的计算一下PGA需要占用的内存空间,再者,假如你的系统不但连接数非常多,而且活跃的连接数也非常的多,那么你可以按照每个进程至少12M的内存来进行估算,更为重要的,系统中假如存在非常多的临时性的计算任务,那么要为PGA预留的内存就更多了。 例如,并行度设置为5创建索引,每个并行进程占用的PGA内存接近1个G:

      用好HugePage,告别Linux性能故障

      用好HugePage,告别Linux性能故障

      所以你在为系统规划PGA内存时不要忘了这些临时性任务需要占用的内存。他们可能是很大的一块哦。

      该为数据库分配多少的PGA内存,除了把连接数的多少这个指标作为一个考量因素外,还需要关注活跃连接数的多少,这是因为很多系统连接数虽然非常的多,但是去数据库里一统计发现,绝大部分的连接已经几个小时甚至几天都没活跃过了,这往往是应用程序的连接池不加以管理的结果(也可能是其他原因)。对于不活跃的连接,Oracle每个进程的PGA占用不会太大,按照10M计算是个合理安全的值。AIX下可以大一些,按照每个15M-20M计算。

      这里再提供一种估算每个空闲的服务器进程占用OS内存的方法。 首先通过操作系统命令free -m查看一下当前OS剩余的内存,69590M

      用好HugePage,告别Linux性能故障

      用好HugePage,告别Linux性能故障

      用好HugePage,告别Linux性能故障

      再次查看剩余的操作系统内存,通过没创建连接之前的剩余内存减去创建完2000个连接之后的剩余内存可以估算出每个进程占用的内存大约为(59332-44548)/ 2000=7M

      用好HugePage,告别Linux性能故障

      读者需要牢记,减少的7M内存中,绝大部分都是进程本身占用的,只有1-2M的内存是PGA占用的。因此上面给大家推荐的值是10-12M,也就是给进程预留出一些PGA的内存来。

      确认一个空闲进程占用的真正PGA内存有多大,可以通过v$process视图中PGA_ALLOC_MEM字段来获得,如下:只有1.49M。但是就像上面已经提到的,这个进程从操作系统层面看却占用了7M左右的内存。

      用好HugePage,告别Linux性能故障

      pga_aggregate_target参数指定的值并不是一个硬限制,直到Oracle 12C才提供了一个参数来强制限制PGA的使用量。如果读者不知道该为自己系统的PGA设置一个什么样的值,可以通过视图v$pgastat中的maximumPGAallocated,totalPGAallocated值作为参考,前者代表自实例启动以来最大的PGA使用峰值,后者代表当前PGA的使用量,不过这个视图最大的缺点是不能看到各个时间段的PGA总体使用情况,这里肉丝给大家提供一个更好的视图来作为参考vsysmetric_history

      用好HugePage,告别Linux性能故障

      上面查询的输出代表了各个时间段的,PGA内存的使用量,结果集并没有完全列出来,读者可以根据PGA各个时间段的使用量来更加精准的去为自己系统的PGA如何做设定做决策。设定PGA的过程是一个循序渐进的过程。再次强调,一个进程占用的内存除了PGA之外,进程本身也会占用内存,这点上面我们已经讨论过。

      按照Oracle 2015年OOW上的一份PPT提到,12C之前版本,PGA最多可用的内存可达到PGA_AGGREGATE_TARGET设定值的三倍,这里你听一下就行了,不必当真。

      如果生产环境真的遭遇了PGA严重使用过量的情况,可以通过Event 10261 来限制某个/所有进程PGA的使用,level后面值的单位为KB。

      用好HugePage,告别Linux性能故障

      一旦进程超出PGA的设定配额,会被后台进程杀掉并报错,不同的版本可能报错的信息不一样:

      For 11.2.0.4 and 12.1.0.1+, ORA-10260

      For 11.1 - 11.2.0.3, ORA-600 [723]

      12C PGA_AGGREGATE_LIMIT

      12C之前的版本对于PGA的使用限制并没有一个硬限制,这个可能会导致一些问题,比如不加以限制后可能会导致OS SWAP的问题,一旦出现SWAP会导致Oracle性能的急剧下降,甚至导致DOWN机,我曾经遭遇过的一个案例是出现SWAP后,LGWR进程本身的内存出现了SWAP,数据库系统的表现是几乎完全HANG死,最后没办法只能重启解决问题。

      对于这个新特性的使用是通过参数PGA_AGGREGATE_LIMIT来限制PGA的使用上线,它是一个推导参数,在使用ASMM情况下,取以下的最大值

      2GB

      200% PGA_AGGREGATE_TARGET

      3MB* PROCESSES

      在使用AMM情况下,肉丝还未找到PGA_AGGREGATE_LIMIT取值的规律,如果你知道,请告诉我哦。

      5MSMM

      10G前SGA的管理是通过手工设置一系列的参数来实现的,例如重要的参数有以下几个:

      buffer_cache_size

      shared_pool_size

      large_pool_size

      stream_pool_size

      log_buffer

      SGA是一大块内存的统称,由上面列出的组件组成,10G之前的版本,DBA需要对SGA的各个内存区域进行手工设置,这可能对一个DBA无形中要求变得非常的高,需要了解业务,了解热点数据量,了解SQL的使用方式,是否存在大量不同文本的SQL等等来决策来给每个区域分配多少内存。使用过这个版本的DBA基本都遭遇过一个经典的报错:ORA-04031,一般是由于shared pool内存不够导致,这个不够的原因可能有很多,共享池内存的严重碎片化,大量的硬解析,巨大的PL/SQL文本等等都可能会导致这个问题。下面我们来看下,手工管理SGA情况下,如何考虑为buffer cache和shared pool这两个最重要的内存组件分配内存。

      Buffer Cache

      Buffer Cache俗称数据块高速缓存,是用来缓存数据块的拷贝的,Oracle通过改进后的LRU算法以期待这些数据块后续被高效的重用。服务器进程从磁盘读入的数据就放在这块内存中,修改数据时,也是在这个区域对数据进行修改。并没有一个给buffer cache分配内存的黄金法则,还是要根据操作系统的内存大小,业务的热点数据量、业务的类型等因素来决定给buffer cache分配多大的内存大小。我们先看下如何决定整个SGA的大小,对于SGA的分配原则,官方建议如下:

      用好HugePage,告别Linux性能故障

      上面的公式格式跟PGA的公式大同小异,刨去20%内存给操作系统之后,分为了不同的系统类型,基本上是OLTP系统,大部分的内存给buffer cache,DSS类的系统,buffer cache没那么重要,可以给到50%甚至更低。 至于SGA中多少可以分配给buffer_cache,要看实际情况。DBA可以通过查看buffer cache的命中率来粗略了解是否给buffer cache分配了足够的内存。但是熟悉我的朋友都知道,我是OWI方法论的践行者,对于命中率的崇拜在Oracle里已然不应该再存在,但是命中率作为一种性能诊断的辅助手段依然具有它的价值。如果系统的SQL都足够优化后,命中率不高,一定程度上意味着可能buffer cache给小了或者你的业务访问的数据非常的离散,热点数量太少。

      这里肉丝给出的优化思路是自顶向下,命中率低是一个表象,最上层的应用是不是调用了大量不需要调用的SQL,这些SQL是不是缺少索引,SQL都足够优化后,DBA是不是考虑加大buffer cache来提升性能,加大之后还是不行,是不是要考虑增加系统内存来进一步提高buffer cache的大小,最后是不是需要为数据库多加几个盘或者使用SSD来提高性能。

      采用自顶向下的分析方法有利于真正发现问题所在而且以最低的代价解决问题,如果仅仅是一个SQL由于缺少索引而导致整个数据库系统缓慢,DBA直接就去加盘扩容IO,那么最终会发现花费了这么大的代价,治标不治本,问题依然没有解决。上面给出的公式并不适用于所有情况,特别是OLTP系统,如果进程数非常的多,那么需要进一步降低SGA占用内存的比例,以预留出更多内存给PGA使用。

      Shared Pool

      Oracle占用量最大的两块内存除了buffer cache区就是Shared Pool的内存了,它的结构非常的复杂,而且由于要缓存SQL代码这种非标准大小的文本,经常会产生大量的碎片化内存,shared pool总体上包含了两大部分,一块是library cache区,用来缓存SQL、PL/SQL代码,保存它们的执行计划,提高SQL的解析效率,如果你的应用代码从来不使用绑定变量,那么这一块的内存对你来说是一个很大的负担,但是Oracle里是无法关闭library cache区的,因此对于OLTP系统,请确保SQL都使用了绑定变量。第二大块区域是row cache区,用来缓存数据库的数据字典,由于保存在里面的信息是以行的形式存在,因此叫row cache。

      对于这一块的内存,依据数据库中元信息(metadata)的多少而决定,如果数据库中有几十万的对象,那么这一块的内存就会占用比较大,同时表上的很多列都有直方图信息,也会导致这一区的内存占用比较大。在一个稳定的系统中,这一区域的内存基本上是静态的,Oracle中几乎没有操作会频繁修改row cache区。有个例外情况是没有cache属性的sequence,如果这种sequence调用频繁,就会触发频繁的修改sequence的属性值,进而可能会产生row cache lock的一些等待,优化的办法是为每一个sequence设置足够的cache值。 >如果应用程序没有使用绑定变量,而且难以修改,可以通过设置cursor_sharing为force来尝试解决问题。

      这里肉丝再讲一个亲身经历的案例,老DBA嘛,可能技能已经不多,但故事还是有的,曾经帮一位客户解决了一个free buffer waits的案例,这个等待事件的出现一般说明buffer cache过小,或者全表扫描、写入操作比较多、写脏数据比较慢,从AWR报告看,free buffer waits排在TOP EVENT的第一名,占用的DB TIME已达到了百分之七八十,而且从awr报告中发现客户的shared pool内存占用已经达到了接近50G,而分析数据库一个月之前的AWR报告,shared pool的内存只有3个G左右的大小,基本上可以认定为shared pool内存占用过大,而导致buffer cache不够用,进而出现了free buffer waits等待事件,经过跟客户沟通后知道,以前一直比较稳定,最近做过的大的变更是给数据库使用了oracle 的flahcache,通过MOS上搜索flashcache关键字最终发现,在11.2.0.4,Oracle RAC如果使用了flash cache,那么会在shared pool 中分配额外的内存存放GCS资源。多出的内存为:208 bytes * the total number of (flash) buffer blocks。因为这里提醒广大DBA朋友,如果你打算使用Oracle的FlashCache那么请为它预留出足够的shared pool内存。

      7ASMM

      10G 版本Oracle推出了ASMM,自动SGA管理,它的出现一定程度上帮助DBA解决了管理SGA的问题,通过设置参数sga_target为非0值来启用ASMM。但是在10GR1,包括10GR2的早期版本,ASMM还不够成熟存在比较多的BUG,导致了比较多的问题,所以当时DBA在一些核心的生产环境,还是沿用了9I时候的手工SGA管理。自动SGA管理,不再需要为每个内存组件设定值,当然如果你设置sga_target的同时,设置了db_cache_size这些参数,那么db_cache_size这些参数值会作为最小值要求。

      如果sga_target设置为0,memory_target也为0,则回归到传统的MSMM管理。通过使用ASMM可以很大程度上解决上面提到的ORA-04031的错误。在使用了ASMM后,去查看spfile文件,会发现多了一些双下划线打头的内存参数如__db_cache_size,这些内存参数是Oracle实例运行过程中动态产生固化到spfile中的,如果实例运行的时间足够长,这些参数的值被固话后,相当于有了一个基于自身环境的最佳实践参数,数据库实例重启后,会沿用固化在spfile中的这些参数值。 > 11G版本即使sga_target设置为0,memory_target也设置为0,也可能会发现SGA的pool之间Granule的移动,这是11G的新Linux特性,通过参数_memory_imm_mode_without_autosga来控制。 >

      Granule

      ASMM技术的实现,内部是通过Granule在内存组件之间移动来实现。这里对Granule做一点解释,Oracle 10G引入的自动共享内存管理,目的是为了解决下面的问题,“我应该把db_cache_size设置为多大?我应该把shared_pool_size设置多大?那么10G以后,Oracle给出的答案是,“你不用再考虑这个问题了,我通过算法帮你搞定“。

      简单来说,就是通过比较通过增加数据块缓存减少的磁盘IO时间与通过增加共享池优化而节省的时间,通过比对,来得出是否需要在两者间来移动内存。为了让内存在db_cache_size和shared_pool_size之间高效移动,Oracle在9I版本中重新构建了SGA,也就是使用固定大小的内存块-Granule,Granule会随着操作系统、Oracle版本以及SGA大小的不同而不同,读者可以通过如下的SQL语句来查看当前实例的Granule的大小:

      用好HugePage,告别Linux性能故障

      in Oracle Database 11.2.0.2 indicates that the granule size increases from 64MB to 128MB when the SGA_TARGET parameter is set to 1 byte greater than 32G, and jumps to 256MB when the SGA_TARGET parameter is set to 1 byte greater than 64G. A granule size of 32MB is possible when the SGA_TARGET was set to a value between 8G + 1 byte to 16G.

      8AMM

      有了PGA的自动管理,SGA的自动管理,Oracle 这个强迫症患者终于在11G这个版本推出了AMM,自动内存管理,由于使用了AMM后就不能使用大页,因此这个功能其实一直没被广泛使用,通过这个功能DBA只需要设置memory_target一个参数就可以完成整个数据库实例内存的配置,就像ASMM导致了一些双下划线隐含参数的产生,AMM同样导致了一些双下划线隐含参数的产生,例如:__pga_aggregate_target,__sga_target。

      而且在11.2.0.2版本之前,DBCA建库默认就是AMM管理(有些时候Oracle胆子真的是很大),11.2.0.3以后开始DBCA建库时会检测操作系统内存大小,大于4G内存默认为ASMM,小于4G内存默认为AMM。同样如果你设置AMM后,也设置了SGA_TARGET等参数,那么这些参数会作为最小值要求。

      AMM最大的问题是不能使用大页内存。关于使用大页的重要性会在本文后面部分详细介绍。 >Doc 749851.1 > > Doc 1453227.1.

      11G后由于出现了AMM,如果你做DBA时间足够长,你一定遇到过下面这个错误

      用好HugePage,告别Linux性能故障

      这个错误给人莫名其妙的感觉,“MEMORY_TARGET特性不被支持”,其实不是特性不被支持,这是由于AMM使用的是操作系统的共享内存文件系统,位于/dev/shm下,如果配置的内存文件系统比较小,小于了memory_target的值就会报错,一般在Linux主流的操作系统上,这个内存共享文件系统的值是内存大小的一半,如果读者遭遇了这个问题,要不去调小memory_target的参数值,要不通过如下办法去修改这个共享内存文件系统的大小:

      用好HugePage,告别Linux性能故障

      这里指出一点,11G ASM默认会使用AMM,官方强烈建议不要修改这个默认行为。ASM里要求MEMORY_TARGET的最小值为256M。如果设置了低于256M的值,Oracle会自动增加内存到256M。 对于ASM的发布版:11.2.0.3/11.2.0.4/12.1,Oracle强烈建议把memory_target设置为1536M,这个值被证明在绝大部分的环境里都是足够的。

      使用了ASM后,数据库实例的shared_pool内存需要重新评估计算,如下公式是在正常shared pool的基础上需要额外增加的大小:

      用好HugePage,告别Linux性能故障

      如果ASM磁盘组是external redundancy,需要在2MB基础上,每100G的空间,增加1MB。

      如果ASM磁盘组是normal redundancy,需要在4MB基础上,每50G的空间,增加1MB。

      如果ASM磁盘组是high redundancy,需要在6MB基础上,每33G的空间,增加1MB。

      ASM & Shared Pool (ORA-4031) (文档 ID 437924.1)

      9大页

      对于类Linux系统,CPU必须把虚拟地址转换程物理内存地址才能真正访问内存。为了提高这个转换效率,CPU会缓存最近的虚拟内存地址和物理内存地址的映射关系,并保存在一个由CPU维护的映射表中,为了尽量提高内存的访问速度,需要在映射表中保存尽量多的映射关系。这个映射表在Linux中每个进程都要持有一份,如果映射表太大,就会大大降低CPU的TLB命中率,主流的Linux操作系统,默认页的大小是4K,对于大内存来说,这会产生非常多的page table entries,上面已经提到,Linux下页表不是共享的,每个进程都有自己的页表,现在随便一个主机的内存都配置的是几十个G,几百个G,甚至上T,如果在上面跑Oracle不使用大页,基本上是找死,因为Oracle是多进程架构的,每一个连接都是一个独占的进程,大内存+多进程+不使用大页=灾难,肉丝在8年的DBA生涯里,至少帮助不下5个客户处理过由于没有使用大页而导致的系统故障,而这5个客户都是近三四年遇到的,为什么大页这个词提前个三五年并没有被频繁提起,而当下,大页这个词在各种技术大会,最佳实践中成为热门词汇?

      这是因为最近几年是Linux系统被大量普及应用的几年,也是大内存遍地开花的几年,而且现在一个数据库系统动不动就是几百上千个连接,这些都促成了大页被越来越多的被关注到。

      大页的好处

      我们来看一下使用了大页的好处:

      少的page table entries,减少页表内存

      pin住SGA,没有page out

      提高TLB命中率,减少内核cpu消耗

      在没有使用大页的系统上,经常可能会发现几十上百G的页表,严重情况下,系统CPU的sys部分的消耗非常大,这些都是没使用大页的情况下的一些症状。

      大页的特点/缺点

      要预先分配

      不够灵活,甚至需要重启主机

      如果分配过多,会造成浪费,不能被其他程序使用。

      大页的分配方法

      通过在文件/etc/sysctl.cnf中增加vm.nr_hugepages参数来为大页设定一个合理的值,值的单位为2MB。或者通过echo 一个值到/proc/sys/vm/nr_hugepages中也可以临时性的对大页进行设定。 至于应该为大页设定多大的值,这个要根据系统SGA的配置来定,一般建议大页的总占用量大于系统上所有SGA总和+2GB。

      HugePages on Oracle Linux 64-bit (文档 ID 361468.1),AIX页表共享,一般不用设置大页。

      大页的原理

      用好HugePage,告别Linux性能故障

      以下的内容是基于32位的系统,4K的内存页大小做出的计算: 1)目录表,用来存放页表的位置,共包含1024个目录entry,每个目录entry指向一个页表位置,每个目录entry,4b大小,目录表共4b*1024=4K大小 2)页表,用来存放物理地址页的起始地址,每个页表entry也是4b大小,每个页表共1024个页表entry,因此一个页表的大小也是4K,共1024个页表,因此页表的最大大小是1024*4K=4M大小 3)每个页表entry指向的是4K的物理内存页,因此页表一共可以指向的物理内存大小为:1024(页表数)*1024(每个页表的entry数)*4K(一个页表entry代表的页大小)=4G 4)操作系统将虚拟地址映射为物理地址时,将虚拟地址的31-22这10位用于从目录表中索引到1024个页表中的一个,将虚拟地址的12-21这10位用于从页表中索引到1024个页表entry中的一个。从这个页表entry中获得物理内存页的起始地址,然后将虚拟地址的0-12位用作4KB内存页中的偏移量,那么物理内存页起始地址加上偏移量就是进出所需要访问的物理内存地址。

      由于32位操作系统不会出现4M的页表,因为一个进程不能使用到4GB的内存空间,有些空间被保留使用,比如用来做操作系统内核的内存。而且页表entry的创建出现在进程访问到一块内存的时候,而不是一开始就创建。

      页表内存计算

      在32位系统下,一个进程访问1GB的内存,会产生1M的页表,如果是在64位系统,将会增大到2M。 很容易推算,如果一个SGA设置为60G,有1500个Oracle用户进程,64位Linux的系统上,最大的页表占用内存为:60*2*1500/1024=175G,是的,你没看错,是175G!但是实际情况看到的页表占用可能没有这么大,打个百分之四五十的折扣,这是因为只有服务器进程访问到SGA的特定区域后,进程才需要把这一块对应的页表项加入到自己的页表中。

      11.2.0.3版本

      11.2.0.3版本之前,如果分配的大页数量不足,那么Oracle启动过程中不会使用大页,转而使用小页,但是在11.2.0.3版本后,Oracle在启动时同样会尝试使用大页,如果大页的数量不够,那么会把当前配置的大页使用完,不够的部分再从小页中去获取,这一行为实际上是通过Oracle的一个参数来控制USE_LARGE_PAGES,后面会对这个参数做详细解释。通过数据库实例的alert文件可以清楚的看到这一情况的发生:

      用好HugePage,告别Linux性能故障

      Total Shared Global Region in Large Pages = 1024 MB (85%),代表只有85%的SGA被放在了大页中。RECOMMENDATION部分,建议你至少增加89个大页来让SGA完全放到大页中。

      USE_LARGE_PAGES

      这个参数用来控制数据库实例启动时,对于大页内存的使用行为。有3个值在11.2.0.3版本之前,11.2.0.3版本多了一个值auto:

      true 默认值,尽可能使用大页,有可能有一些页在大页中,有一些在小页中,这种情况下通过操作系统命令ipcs -ma可能会看到内存分段(内存分段可能有多重情况都会导致,例如开启numa也可能会导致内存分段)

      false 不使用大页

      only 选项代表强制使用大页,否则无法启动

      auto (11.2.0.3)在实例启动时,通过后台进程dism echo xxx > /proc/sys/vm/nr_hugepages 来尽可能的使用大页

      以下代码为在参数设置为auto情况下alert的输出:

      用好HugePage,告别Linux性能故障

      可以看到启动实例过程中,优先启动了DISM进程,通过这个进程来自动完成大页的配置。$Oracle_HOME/bin/oradism的权限也是root权限,因为如果是grid权限不能完成大页的配置echo xxx > /proc/sys/vm/nr_hugepages。

      Transparent Hugepage

      从RedHat6, RedHat7, OL6, OL7 SLES11 和 UEK2 kernels开始transparent hugepage被默认开启,它允许大页做动态的分配,而不是系统启动后就分配好,根据Oracle MOS DOC:1557478.1,transparent hugepage导致了很多的问题,建议将其关闭 查看是否启用了transparent hugepage cat /sys/kernel/mm/transparent_hugepage/enabled [always] never []内的值是当前启用的值,上面的输出说明启用了transparent hugepage。 可以通过 /etc/grub.conf 文件来关闭transparent hugepage。

      用好HugePage,告别Linux性能故障

      通过增加关键字transparent_hugepage=never来讲transparent hugepage关闭。 也可以通过开机启动后,echo相应的值到对应的文件来动态关闭transparent hugepage。

      用好HugePage,告别Linux性能故障

      OS层面查看大页使用情况

      cat /proc/meminfo

      HugePages_Total: 43000

      HugePages_Free: 29493

      HugePages_Rsvd: 23550

      Hugepagesize: 2048 kB

      HugePages_Total为所分配的页面数目,和Hugepagesize相乘后得到所分配的内存大小。43000*2/1024大约为84GB。

      HugePages_Free为从来没有被使用过的Hugepages数目。即使Oracle sga已经分配了这部分内存,但是如果没有实际写入,那么看到的还是Free的。这是很容易误解的地方。

      HugePages_Rsvd为已经被分配预留但是还没有使用的page数目。在Oracle刚刚启动时,大部分内存应该都是Reserved并且Free的,随着Oracle SGA的使用,Reserved和Free都会不断的降低。

      HugePages_Free – HugePages_Rsvd 这部分是没有被使用到的内存,如果没有其他的Oracle instance,这部分内存也许永远都不会被使用到,也就是被浪费了。在该系统上有11.5GB的内存被浪费了。

      10最佳实践

      对于Oracle来说,这是一个最佳实践泛滥的时代,所有的最佳实践其实都有特定的应用场景,而不是放之四海皆准,但是当今信息爆炸时代(数据库种类爆炸时代),很多DBA没有那么多的耐心去专注学习一门数据库,只是拿来主义从网上找出一些最佳实践来,不管三七二十一就用到自己的环境中(甚至是生产环境中),一定程度上来说,崇拜最佳实践是懒惰的结果。

      针对于Oracle的内存分配方式,肉丝给大家推荐在核心系统上:

      1.使用手工的SGA管理,这种管理方式已经非常的成熟,但是这种方式对DBA要求较高,一定程度上需要了解业务特点。

      2.如果第一种方法你感觉到比较难,那么使用ASMM,但是为buffer cache,shared pool设定最小值的方式,这种方式是我非常推荐的方式。

      至于AMM这种内存分配方式,由于不能使用大页,建议不要去用。

      具体到内存如何分配,针对是OLTP场景,还是OLAP场景,有着不同的内存分配原则,即使是OLTP场景,针对进程数的多少,并发数的多少,SQL语句的特点,都会导致产生不同的内存分配方法。作为DBA要掌握基本的Oracle内存使用原理,然后根据实际情况去根据业务自身特点分配内存。

      不管是OLTP系统或者OLAP系统,一般都建议至少为操作系统预留出20%的内存空间,这些内存空间用于kernal、page table以及一些其他的进程需要,例如rman备份,文件系统缓存。这个也是Oracle官方的建议。

      把这一部分的内存刨去后,针对OLTP系统,可以考虑先尝试预留出20%的内存给PGA使用,80%的内存给SGA使用。如果系统上进程数比较多,特别是同时活跃的进程数比较多,需要给PGA预留出更多的内存,可以按照每个进程12M的PGA占用进行计算。

      针对OLAP系统,刨去操作系统的预留内存后,可以考虑预留出50%的内存给PGA使用,50%的内存给SGA使用。毕竟在纯OLAP下,buffer cache其实不需要那么大的内存空间。

      用好HugePage,告别Linux性能故障

      SGA、PGA分配好后,要考虑到是否需要为buffer cache、shared pool来手工设定一个值,就像上文已经提到过的,可以参考buffer cache 的命中率,Library Hit的命中率作为一个辅助参考.如果命中率较低,有可能是内存分配的不够合理。

      当然你还需要借助于像AWR报告这样的工具,根据SQL的执行计划等内容来进一步的做诊断,比如命中率低的原因可能不是分配的buffer cache小,而是存在大量的低效的全表扫描,进而导致命中率低,这样的话,需要优化的就是SQL,而不是继续加大buffer cache。再比如,如果你发现Library cache Hit比较低,可能并不是shared pool比较小,还可能是系统的SQL存在大量未使用绑定变量的情况,导致硬解析过重。

      优化经常是个系统工程,不能一蹴而就,特别像Oracle是一个很庞大的复杂系统,对于问题的出现,更是要仔细推敲,不能轻易的下结论。随着做DBA时间越来越长,你也会越来越懂TOM的一句话:It depends。

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.51cto.com/lhrbest/3262090,作者:小麦苗DB宝,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:MySQL 8.0解决Too many connections数据库连接数被打满

      下一篇:Mybatis-Plus动态表名插件实现数据库分表查询

      相关文章

      2025-05-19 09:04:30

      ORA-01110: data file 1: '/u01/app/oracle/oradata/orcl151/system01.dbf'

      ORA-01110: data file 1: '/u01/app/oracle/oradata/orcl151/system01.dbf'

      2025-05-19 09:04:30
      data , oracle
      2025-05-14 10:33:25

      超级好用的C++实用库之网络

      在网络相关的项目中,我们经常需要去获取和设置设备的IP地址、子网掩码、网关地址、MAC地址等信息。这些信息一般与操作系统相关,在Windows系统和Linux系统上调用的接口是不一样的。

      2025-05-14 10:33:25
      Linux , 参数 , 地址 , 接口 , 网卡 , 返回值
      2025-05-14 10:03:13

      超级好用的C++实用库之线程基类

      在C++中,线程是操作系统能够进行运算调度的最小单位。一个进程可以包含多个线程,这些线程共享进程的资源,比如:内存空间和系统资源,但它们有自己的指令指针、堆栈和局部变量等。

      2025-05-14 10:03:13
      Linux , void , Windows , 函数 , 操作系统 , 线程
      2025-05-14 10:03:13

      一步一步在linux上部署Oracle 11g R2 RAC 【1】

      一步一步在linux上部署Oracle 11g R2 RAC 【1】

      2025-05-14 10:03:13
      app , oracle , 主机名 , 磁盘
      2025-05-13 09:51:29

      搭建ogg双向复制时,oracle 19.16向oracle 10.2.0.4 ogg复制时报警OGG-01389、OGG-02246处理记录

      搭建ogg双向复制时,oracle 19.16向oracle 10.2.0.4 ogg复制时报警OGG-01389、OGG-02246处理记录

      2025-05-13 09:51:29
      ogg , OGG , oracle , 复制
      2025-05-13 09:51:29

      oracle使用dblink impdp数据时报错ORA-39169

      oracle使用dblink impdp数据时报错ORA-39169

      2025-05-13 09:51:29
      ORA , oracle
      2025-05-13 09:51:17

      配置ogg同步oracle 11g数据到oracle 19c

      配置ogg同步oracle 11g数据到oracle 19c

      2025-05-13 09:51:17
      ogg , oracle , 同步
      2025-05-13 09:51:17

      使用Kernel 2.6版本的Linux系统运行dbca创建数据库实例时报错ORA-27125

      使用Kernel 2.6版本的Linux系统运行dbca创建数据库实例时报错ORA-27125

      2025-05-13 09:51:17
      dbca , Linux , ORA
      2025-05-13 09:50:59

      测试oracle主键被激活后,依赖该列的外建需手动重新激活

      测试oracle主键被激活后,依赖该列的外建需手动重新激活

      2025-05-13 09:50:59
      oracle , 主键 , 激活
      2025-05-13 09:50:48

      更改备库自动生成数据文件路径

      更改备库自动生成数据文件路径

      2025-05-13 09:50:48
      app , oracle
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5243901

      查看更多

      最新文章

      ORA-01110: data file 1: '/u01/app/oracle/oradata/orcl151/system01.dbf'

      2025-05-19 09:04:30

      搭建ogg双向复制时,oracle 19.16向oracle 10.2.0.4 ogg复制时报警OGG-01389、OGG-02246处理记录

      2025-05-13 09:51:29

      oracle使用dblink impdp数据时报错ORA-39169

      2025-05-13 09:51:29

      更改备库自动生成数据文件路径

      2025-05-13 09:50:48

      oracle表字段设置为unused的相关知识

      2025-05-13 09:50:48

      oracle数据库中删除表后创建同名表,如何闪回删除后的表?

      2025-05-13 09:50:48

      查看更多

      热门文章

      oracle 数据库 中 如何将不带汉字的日期格式转换成带“年月日时分秒”格式的日期

      2023-04-06 06:11:29

      CentOS 7中安装Oracle JDK1.8环境

      2023-05-18 09:33:22

      Linux 资源信息统计写入SQLServer(顺便学习Linux命令awk,sed)

      2023-06-19 06:59:01

      oracle字符串处理函数(部分)

      2022-12-29 09:29:46

      关于jpa的Specification自定义函数,实现oracle的decode;以及如何在静态方法中调用注入的service

      2022-12-26 09:32:18

      Oracle 10g在solaris 10下的自动运行脚本

      2022-11-16 11:58:11

      查看更多

      热门标签

      数据库 mysql 字符串 数据结构 MySQL 算法 redis oracle java sql python 数据 索引 SQL 查询
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      oracle之单行函数之子查询

      oracle学习23-区分大小写和字符集不同

      oracle学习-rman备份-控制文件丢失恢复

      从Sql Server取数据到DataSet,再插入Oracle的表

      oracle 11g分区表相关知识

      快速恢复区备份集清理操作演练

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号