于提高性能和高可用性的增强功能。具体包括:
通过自动区域映射允许,基于查询中的谓词修剪块和分区,无需任何用户干预
压缩SecureFileLOB回收空间并提高性能
通过AutomaticIn-Memory自动动态创建内存对象
通过内存混合扫描,自动选择最佳方法来扫描内存中和非内存中列数据的记录。进而将性能提高几个数量级
使用新的初始化参数MAX_IDLE_BLOCKER_TIME终止阻塞会话
实验1:使用自动区域映射

这项技术在19c当中已经为大家提供,但那时需要DBA手工指定,在21c当中,创建和维护区域映射可以自动完成。

在这个实验中,我们首先查询几次sales_zm表,然后在统计信息中的一致性读的计数。比如在下面,我们执行了两次查询,得到的一致性读计数都为15370。
SQLSETAUTOTRACEONSTATISTICSQLSELECTCOUNT(DISTINCTsale_id)FROMsales_zmWHEREcustomer_id=50;
COUNT(DISTINCTSALE_ID)----------------------100
Statistics----------------------------------------------------------0recursivecalls0dbblockgets15370consistentgets0physicalreads7084redosize582bytessentviaSQL*Nettoclient52bytesreceivedviaSQL*Netfromclient2SQL*Netroundtripsto/fromclient0sorts(memory)0sorts(disk)1rowsprocessed
SQLSELECTCOUNT(DISTINCTsale_id)FROMsales_zmWHEREcustomer_id=50;
COUNT(DISTINCTSALE_ID)----------------------100
Statistics----------------------------------------------------------0recursivecalls0dbblockgets15370consistentgets0physicalreads7084redosize582bytessentviaSQL*Nettoclient52bytesreceivedviaSQL*Netfromclient2SQL*Netroundtripsto/fromclient0sorts(memory)0sorts(disk)1rowsprocessed
在没有启动自动区域映射之前,和之前版本的数据库一样,如果要对某个表设置区域映射,需要手工完成。这里需要注意的是,因为当前的表中已经有数据了,所以我们在对表启用区域映射之后,对它使用move,进行“重整”。
SQLALTERTABLEsales_zmADDCLUSTERINGBYLINEARORDER(customer_id)WITHMATERIALIZEDZONEMAP;
Tablealtered.
SQLALTERTABLEsales_zmMOVE;
Tablealtered.
这回我们再次执行之前的相同查询,观察一致性读的计数,我们会发现由原来的15370,降低到1096,性能提升了14倍。
SQLSELECTCOUNT(DISTINCTsale_id)FROMsales_zmWHEREcustomer_id=50;
COUNT(DISTINCTSALE_ID)----------------------100
Statistics----------------------------------------------------------recursivecallsdbblockgets1096consistentgets0physicalreads1308redosize582bytessentviaSQL*NettoclientbytesreceivedviaSQL*NetfromclientSQL*Netroundtripsto/fromclientsorts(memory)0sorts(disk)rowsprocessed
如果想了解哪些表已经创建区域映射,可以通过如下语句进行查询。
SQLselectFACT_TABLE,ZONEMAP_NAMEFROMdba_zonemaps;
FACT_TABLEZONEMAP_NAME----------------------------------------SALES_ZMZMAP$_SALES_ZM
如果想让系统自动为新创建的表开启区域映射功能,可以使用DBMS包来完成,让我们通过如下实验来验证,首先,我们将之前创建的表删除,然后开启系统自动区域映射,然后再创建表,在表中的数据稳定之后,我们先收集一下表上面的统计值。
SQLDROPTABLEsales_zmPURGE;
Tabledropped.
SQLSELECTzonemap_name,automatic,partly_stale,incompleteFROMdba_zonemaps;
norowsselected
SQLEXECDBMS_AUTO_('AUTO_ZONEMAP_MODE','ON')
PL/SQLproceduresuccessfullycompleted.
SQLCREATETABLEsales_zm(sale_idNUMBER(10),customer_idNUMBER(10));
Tablecreated.
SQLDECLAREiNUMBER(10);BEGINFORiIN1..80LOOPINSERT/*+APPEND*/INTOsales_zmSELECTROWNUM,MOD(ROWNUM,1000)FROMdualCONNECTBYLEVEL=100000;COMMIT;ENDLOOP;END;/
PL/SQLproceduresuccessfullycompleted.
SQLEXECdbms__table_stats(ownname=,tabname='SALES_ZM')
PL/SQLproceduresuccessfullycompleted.
接下来,让我们执行与之前相同的查询,看看一致性读的计数。
SQLSELECTCOUNT(DISTINCTsale_id)FROMsales_zmWHEREcustomer_id=50;
COUNT(DISTINCTSALE_ID)----------------------100
Statistics----------------------------------------------------------recursivecallsdbblockgets15365consistentgets15280physicalreads1964redosize582bytessentviaSQL*NettoclientbytesreceivedviaSQL*NetfromclientSQL*Netroundtripsto/fromclient0sorts(memory)0sorts(disk)rowsprocessed
通过观察,我们发现一致性读的计数很高,似乎区域映射没有起作用。这是因为区域映射将在后台延迟执行,如果您迫不及待想看到区域映射的结果,可以使用sys用户通过如下语句进行刷新。
_auto_zonemap__execute;
PL/SQLproceduresuccessfullycompleted.
这回再让我们看看查询结果。
SQLSELECTzonemap_name,automatic,partly_stale,incompleteFROMdba_zonemaps;
ZONEMAP_NAMEAUTOMATICPARTLY_STALEINCOMPLETE-----------------------------------------------------ZMAP$_SALES_ZMYESNONO
如果想了解系统创建自动区域映射的情况,可以通过DBA_ZONEMAP_AUTO_ACTIONS进行查询。
SQLSELECTtask_id,msg_id,action_msgFROMdba_zonemap_auto_actions;
TASK_IDMSG_IDACTION_MSG----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------188BS:Currentexecutiontaskid:7Executionname:SYS_ZMAP_2022-04-11/07:19:13TaskName:ZMAP_TASK1189BS:********ZonemapBackgroundActionReportforTaskID:7****************190BS:******ofZonemapBackgroundActionReportforTaskID:7**********164BS:Currentexecutiontaskid:7Executionname:SYS_ZMAP_2022-04-11/07:17:04TaskName:ZMAP_TASK1165BS:********ZonemapBackgroundActionReportforTaskID:7****************166TP:Tryingtocreatezonemapontable:SALESowner:SH167AL:Blockcount:16384,samplepercentis:3.051758168TP:colname:AMOUNT_SOLD:clusteringratio:.28169TP:colname:CHANNEL_ID:clusteringratio:1170TP:colname:CUST_ID:clusteringratio:.14171TP:colname:PROD_ID:clusteringratio:.97172TP:colname:PROMO_ID:clusteringratio:.2173TP:colname:QUANTITY_SOLD:clusteringratio:1174TP:colname:TIME_ID:clusteringratio:.03175TP:Candidatecolumnlist:AMOUNT_SOLD,CUST_ID,PROMO_ID,TIME_ID176TP:Newzonemapname:ZMAP$_SALES177TP:CreatingnewzonemapZMAP$_SALESontableSALESownerSHtablespaceUSERS178BS:succesfullycreatedzonemap:ZN:ZMAP$_SALESBT:SALESSN:SHCL:AMOUNT_SOLD,CUST_ID,PROMO_ID,TIME_IDCT:+0000:00:00.836940TS:2022-04-11/07:17:06DP:8179TP:Tryingtocreatezonemapontable:SALES_ZMowner:SALES180AL:Blockcount:15280,samplepercentis:3.272251181TP:colname:CUSTOMER_ID:clusteringratio:.99182TP:colname:SALE_ID:clusteringratio:.03183TP:Candidatecolumnlist:SALE_ID184TP:Newzonemapname:ZMAP$_SALES_ZM185TP:CreatingnewzonemapZMAP$_SALES_ZMontableSALES_ZMownerSALEStablespaceSYSTEM186BS:succesfullycreatedzonemap:ZN:ZMAP$_SALES_ZMBT:SALES_ZMSN:SALESCL:SALE_IDCT:+0000:00:01.527002TS:2022-04-11/07:17:07DP:8187BS:******ofZonemapBackgroundActionReportforTaskID:7**********
rowsselected.
显示自动任务运行的活动报告的另一种方法是使用DBMS_AUTO__REPORT函数。
SQLSELECTdbms_auto__report(systimestamp-2,systimestamp,'TEXT')FROMdual;
DBMS_AUTO__REPORT(SYSTIMESTAMP-2,SYSTIMESTAMP,'TEXT')--------------------------------------------------------------------------------/orarep/autozonemap/main%3flevel%3dGENERALSUMMARY-------------------------------------------------------------------------------ActivityStart09-APR-202207:28:11.000000000+00:00Activity11-APR-202207:28:11.359120000+00:00TotalExecutions2-------------------------------------------------------------------------------
EXECUTIONSUMMARY-------------------------------------------------------------------------------zonemapscreated2zonemapscompiled0zonemapsdropped0Stalezonemapscompleterefreshed0Partlystalezonemapsfastrefreshed0Incompletezonemapsfastrefreshed0-------------------------------------------------------------------------------
NEWZONEMAPSDETAILS-------------------------------------------------------------------------------ZonemapBaseTableSchemaOperationtimeDatecreatedDOPColumnlistZMAP$_SALESSALESSH00:00:00.832022-04-11/07:17:068AMOUNT_SOLD,CUST_ID,PROMO_ID,TIME_IDZMAP$_SALES_ZMSALES_ZMSALES00:00:01.522022-04-11/07:17:078SALE_ID-------------------------------------------------------------------------------
ZONEMAPSMAINTENANCEDETAILS-------------------------------------------------------------------------------ZonemapPreviousStateCurrentStateRefreshTypeOperationTimeDopDateMaintained-------------------------------------------------------------------------------
FINDINGS-------------------------------------------------------------------------------ExecutionNameFindingNameFindingReasonFindingTypeMessage
可以通过如下查询了解所有执行中创建了多少区域映射。
SQLSELECT*FROMdba_zonemap_auto_actionsWHEREaction_msgLIKE'%succesfullycreatedzonemap:%'ORDERBYTIME_STAMP;
TASK_IDMSG_IDEXEC_NAMEACTION_MSGTIME_STAMP---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------178SYS_ZMAP_2022-04-11/07:17:04BS:succesfullycreatedzonemap:ZN:ZMAP$_SALESBT:SALESSN:SHCL:AMOUNT_SOLD,CUST_ID,PROMO_ID,TIME_IDCT:+0000:00:00.836940TS:2022-04-11/07:17:06DP:811-186SYS_ZMAP_2022-04-11/07:17:04BS:succesfullycreatedzonemap:ZN:ZMAP$_SALES_ZMBT:SALES_ZMSN:SALESCL:SALE_IDCT:+0000:00:01.527002TS:2022-04-11/07:17:07DP:8
接下来我们对数据表进行大量的更新,然后观察系统对区域映射的维护情况。PARTLY_STALE下方出现了Yes。
8000rowsupdated.
8000rowsupdated.
8000rowsupdated.
8000rowsupdated.
Commitcomplete.SQLSELECTzonemap_name,automatic,partly_stale,incompleteFROMdba_zonemaps;2
ZONEMAP_NAMEAUTOMATICPARTLY_STALEINCOMPLETE-----------------------------------------------------ZMAP$_SALES_ZMYESYESNO
实验2:收缩SecureFileLOB
LOB是我们经常使用的数据类型,用来存储较大的对象,根据数据库的配置,该类型可以存储8TB到128TB的对象。BasicFilesLOB和SecureFilesLOB是Oracle数据库的两种存储类型。某些高级功能可应用于SecureFilesLOB,包括压缩和重复数据删除(高级压缩选件的一部分)和加密(高级安全选件的一部分)。在21c中,我们可以对SecureFilesLOB对象进行收缩,从而提高空间利用率。
首先我们创建一个带有CLOB的表,并开启数据文件的自动扩展:
(aCLOB)LOB(a)STOREASSECUREFILETABLESPACEusers;
Tablecreated.
SQLalterdatabasedatafile'/u02/app/oracle/oradata/pdb21/'autoexton;
Databasealtered.
接下来我们尝试插入和更新行后收缩SecureFileLOB,看看效果如何。通过观察,本次没有block被释放。
('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
rowcreated.
*;
rowcreated.
*;
rowscreated.
*;
rowscreated.
*;
rowscreated.
=a||a||a||a||a||a||a;
rowsupdated.
=a||a||a||a||a||a||a;
rowsupdated.
SQLCOMMIT;
Commitcomplete.
(a)(SHRINKSPACE);
Tablealtered.
SQLSELECT*FROMv$securefile_shrink;
LOB_OBJDSHRINK_STATUSSTART_TIMEEND_TIMEBLOCKS_MOVEDBLOCKS_FREEDBLOCKS_ALLOCATEDEXTENTS_ALLOCATEDEXTENTS_FREEDEXTENTS_SEALEDCON_ID------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------76993+00:00-+00:00000接下来,我们对这个表进行一些更新,然后在收缩这个表,最后查询一下这次的收缩效果。
=a||a||a||a||a||a||a;
rowsupdated.
=a||a||a||a||a||a||a;
rowsupdated.
=a||a||a||a||a||a||a;
rowsupdated.
=a||a||a||a||a||a||a;
rowsupdated.
SQLCOMMIT;
Commitcomplete.
(a)(SHRINKSPACE);
Tablealtered.SQLselectblocks_freedFROMv$securefile_shrinkWHERELOB_OBJD=76993;
BLOCKS_FREED------------4410
通过观察,我们发现,本次的效果比较明显,释放了4410个块。随着对这个表操作的增加,对表进行收缩的效果越加明显。建议您在不影响系统性能的前提下,经常对带有SecureFileLOB的表进行收缩,从而合理利用存储资源。
实验3:AutomaticIn-Memory
In-Memory技术在12c当中就已经为大家提供了,不算是什么新的技术。但是在21c中,提供了自动IM功能,进一步减轻DBA的负担,其实这项功能,在之前的数据库版本中就有体现。只不过当时需要配合特定环境才能使用。
首先让我们查询数据字典,以确定HR表是否指定为INMEMORY。
SQLSELECTtable_name,inmemory,inmemory_compressionFROMdba_tablesWHEREowner='HR';
TABLE_NAMEINMEMORYINMEMORY_COMPRESS-------------------------------------------COUNTRIESDISABLEDEMPENABLEDFORQUERYLOWREGIONSDISABLEDLOCATIONSDISABLEDDEPARTMENTSDISABLEDJOBSDISABLEDEMPLOYEESDISABLEDJOB_HISTORYDISABLED
8rowsselected.
接下来,我们修改_HISTORY表的IM属性,为他添加INMEMORYMEMCOMPRESSFORCAPACITYLOW。修改后,再次查询,我们发现最后一行的表属性已经发生了变化。
_historyINMEMORYMEMCOMPRESSFORCAPACITYLOW;
Tablealtered.
SQLSELECTtable_name,inmemory,inmemory_compressionFROMdba_tablesWHEREowner='HR';
TABLE_NAMEINMEMORYINMEMORY_COMPRESS-------------------------------------------COUNTRIESDISABLEDEMPENABLEDFORQUERYLOWREGIONSDISABLEDLOCATIONSDISABLEDDEPARTMENTSDISABLEDJOBSDISABLEDEMPLOYEESDISABLEDJOB_HISTORYENABLEDFORCAPACITYLOW
8rowsselected.
上面介绍的是手动指定IM的情况。接下来,让我们看看如何制动指定IM。
SQLCONNECT/ASSYSDBAConnected.SQLALTERSYSTEMSETINMEMORY_AUTOMATIC_LEVEL=HIGHSCOPE=SPFILE;
Systemaltered.
SQLexit
设定之后,需要重启数据库。接下来,让我们看看HR中表的情况。
SQLSELECTtable_name,inmemory,inmemory_compressionFROMdba_tablesWHEREowner='HR';
TABLE_NAMEINMEMORYINMEMORY_COMPRESS-------------------------------------------------------COUNTRIESDISABLEDEMPENABLEDFORQUERYLOWREGIONSDISABLEDLOCATIONSDISABLEDDEPARTMENTSDISABLEDJOBSDISABLEDEMPLOYEESDISABLEDJOB_HISTORYENABLEDFORCAPACITYLOW
8rowsselected.
为什么没有变化,除了我们之前手动设定IM的表之外,其他表依旧没有启动IM功能?让我们查看一下初始化参数设置。
SQLSHOWPARAMETERINMEMORY_AUTOMATIC_LEVEL
NAMETYPEVALUE-----------------------------------------------------------------------------inmemory_automatic_levelstringLOWSQLSELECTispdb_modifiableFROMv$parameterWHEREname='inmemory_automatic_level';
ISPDB-----TRUE
我们发现是当前的INMEMORY_AUTOMATIC_LEVEL设定为LOW,我们将它修改为HIGH,然后在重启数据库。
SQLSELECTtable_name,inmemory,inmemory_compressionFROMdba_tablesWHEREowner='HR';
TABLE_NAMEINMEMORYINMEMORY_COMPRESS---------------------------------------------COUNTRIESDISABLEDEMPENABLEDFORQUERYLOWREGIONSENABLEDAUTOLOCATIONSENABLEDAUTODEPARTMENTSENABLEDAUTOJOBSENABLEDAUTOEMPLOYEESENABLEDAUTOJOB_HISTORYENABLEDFORCAPACITYLOW
rowsselected.
除了JOB_HISTORY和EMP是之前手工设定的之外,其他标的IM属性都发生了变化。需要注意的是,如果您看到的结果与上面不同,依旧没有变成ENABLEDAUTO,别着急,请稍等片刻,后台刷新需要一点时间。
但是我们发现,在上面的结果中,有一张表名字为COUNTRIES,它的IM状态为DISABLED。我们通过执行下面的语句,您就知道为什么它无法使用IM技术了。
;*ERRORatline:ORA-64358:in-memorycolumnstorefeaturenotsupportedforIOTs
因为它是IOT表。
接下来我们看看刚才设定的表,在被查询的时候,是否可以被载入系统的IM列存储。我们首先执行大量查询,然后通过动态视图查看系统的IM使用情况。
SQLSELECT/*+FULL()NO_PARALLEL()*/count(*);COUNT(*)----------107
SQLSELECT/*+FULL()NO_PARALLEL()*/count(*);
COUNT(*)----------
SQLSELECT/*+FULL()NO_PARALLEL()*/count(*);
COUNT(*)----------
SQLSELECT/*+FULL()NO_PARALLEL()*/count(*);
COUNT(*)----------
SQLSELECT/*+FULL()NO_PARALLEL()*/count(*);
COUNT(*)----------
SQLSELECT/*+FULL()NO_PARALLEL()*/count(*);
COUNT(*)----------3506176
通过下方的查询,发现有两张表已经在IM的列存储当中。
SQLSELECTsegment_name,inmemory_size,bytes_not_populated,inmemory_compressionFROMv$im_segments;
SEGMENT_NAMEINMEMORY_SIZEBYTES_NOT_POPULATEDINMEMORY_COMPRESS-----------------------------------------------------------------------------------------EMP444334080FORQUERYLOWEMPLOYEES13107200AUTO
实验4:使用新的MAX_IDLE_BLOCKER_TIME初始化参数处理阻塞问题
在数据库操作中,有时会遇到会话阻塞的问题,在21c中,可以通过初始化参数MAX_IDLE_BLOCKER_TIME来自动解决阻塞的会话。这个参数的单位为分钟。比如通过如下语句,将该参数设定为2分钟。
SQLsystemALTERSYSTEMSETmax_idle_blocker_time=2;Systemaltered.
SQLsystemSHOWPARAMETERmax_idle_blocker_time
NAMETYPEVALUE------------------------------------------------------------------------max_idle_blocker_timeinteger2SQLsystem
我们新开一个Terminal,然后对数据进行更新,但不提交。
=salary*2;107rowsupdated.
SQLhr
然后会到原来的Terminal,也做更新的动作。我们会发现,该更新动作被阻塞。
_pct=0;
两分钟之后,将看到如下结果,更新成功。
107rowsupdated.SQLsystem
然后回到上一个Terminal(提示符为hr的Terminal),将看到如下输出:
;*ERRORatline1:ORA-03113:-of-fileoncommunicationchannelProcessID:32314SessionID:274Serialnumber:8179
如果想了解具体后台的处理动作,您可以检查数据库的trace文件,获取更多详细信息。
今天的内容就到这里,我们将在下次的文章中为您介绍OracleDatabase21c中数据泵的新特性,感谢您的阅读,谢谢。
手把手系列文章:
手把手教你21c新特性(1):软件安装与应用程序开发
手把手教你21c新特性(2):大数据与数据仓库新特性
手把手教你升级到Database19c(1)
手把手教你升级到Database19c(2)
手把手教你升级到Database19c(3)
手把手教你19c新特性:自动索引
手把手教你19c新特性:实时统计信息收集
手把手教你19c新特性:混合分区表
手把手教你19c新特性:SQL隔离
手把手教你:使用Kettle实现数据同步
手把手教你:使用Kettle实现数据同步(2)
手把手教你:搭建DataScience环境
手把手教你:使用OracleDataScience分析纽约民宿数据
手把手教你:使用OracleAutoML进行预测(实战教程)
手把手教你OCI机器视觉(1):通过控制台使用OCIVision
