干 DBA 这么多年,我经常会整理收集和编写一些好的运维SQL,并将这些SQL整理到自己的运维SQL手册里,不知不觉已经收集的超过400多页了,现在我也希望能给众多DBA运维带来一些帮助,为大家分享出来。
今天整理的这 6 条,全是我日常天天用的,每一条都在生产环境验证过 N 遍。没有废话,全是干货,收藏起来当速查手册,遇到问题直接复制粘贴就行。
1)PDB添加删除service_name
多租户第一大坑:创建完 service,重启 CDB 就没了。两种方式:方式一用 PL/SQL,适合单机和临时测试,一定要执行 save state,不然必丢。方式二是 RAC 官方标准,用 srvctl 写到 OCR,重启自动生效。别搞成单节点优先,不然 RAC 白搭。
方式一 #该方式重启后service_name不会启动
##PDB添加service_name
column con_id format 99
column pdb format a15
column network_name format a30
select con_id, pdb, network_name from cdb_services where pdb is not null and con_id > 2 order by pdb;
alter session set container=cman;
exec dbms_service.create_service('cman.crmdb', 'cman.crmdb');
##单机采用如下方式启动service
exec dbms_service.start_service('cman.crmdb');
##如果是RAC环境需如下启动service
exec dbms_service.start_service('cman.crmdb', DBMS_SERVICE.ALL_INSTANCES);
##RAC方式采用如下方式保存
alter pluggable database cman save state instances=all;
##单机采用如下方式保存
alter pluggable database cman save state;
##PDB删除service_name
alter session set container=cman;
exec dbms_service.stop_service('cman.crmdb', DBMS_SERVICE.ALL_INSTANCES);
exec dbms_service.delete_service('cman.crmdb');
方式二: RAC 添加service_name,重启后继续生效
su -- oracle
srvctl add service -db cmancdb -service cmantrans.host365 -pdb cmantrans -preferred cmancdb1,cmancdb2
srvctl start service -d cmancdb -s cmantrans.host365
#下面这种方式添加service,应用就会首先连实例一,未做到负载均衡
srvctl add service -db crmcdb -service cman.host365 -pdb cmanTRANS -preferred crmcdb1 -available crmcdb2
2) CDB-PDB环境修改max_string_size
高危操作,一步错全库崩。网上很多教程只改 CDB 参数,漏跑脚本,最后 PDB 全打不开。如下是标准流程,RAC 和单机通用。操作前必须备份,留足维护窗口。
alter system set cluster_database = false scope = spfile;
srvctl stop database -d dbname
ALTER SESSION SET CONTAINER=CDB$ROOT;
ALTER SYSTEM SET max_string_size=extended SCOPE=SPFILE sid='*';
shutdown immediate;
startup upgrade;
cd $ORACLE_HOME/rdbms/admin
sudo mkdir -p /scratch/mydir/utl32k_cdb_pdbs_output
sudo chown -R oracle:oinstall /scratch
sudo chmod -R 777 /scratch
$ORACLE_HOME/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl -u SYS --force_pdb_mode 'UPGRADE' -d $ORACLE_HOME/rdbms/admin -l '/scratch/mydir/utl32k_cdb_pdbs_output' -b utl32k_cdb_pdbs_output utl32k.sql
## 根据提示输入sys密码
shutdown immediate;
startup;
sudo mkdir -p /scratch/mydir/utlrp_cdb_pdbs_output
$ORACLE_HOME/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl -u SYS --force_pdb_mode 'READ WRITE' -d $ORACLE_HOME/rdbms/admin -l '/scratch/mydir/utlrp_cdb_pdbs_output' -b utlrp_cdb_pdbs_output utlrp.sql
alter system set cluster_database = true scope = spfile;
3)PDB如何开机自启动
新手必问:为什么重启 CDB 后 PDB 全是 mount 状态?12cR2 以后用save state就行,官方推荐,简单优雅。老版本或者需要统一打开所有 PDB 的,用触发器。
alter pluggable database pdb_name save state instances=all;
# sys用户
CREATE TRIGGER open_pdbs
AFTER STARTUP
ON DATABASE
BEGIN
EXECUTE IMMEDIATE 'alter pluggable database all open';
END open_all_pdbs;
/
4)CDB---PDB查询参数值
多租户参数继承巨坑:很多参数 PDB 可以单独覆盖,优先级比 CDB 高。别再只查 CDB 的 v$parameter 了。这两个语句,一个查 spfile 里改了什么,一个查每个 PDB 实际生效的是什么,排查参数问题一查一个准。
set lines 1000 longchunksize 9999 head off pages 0
col sid for a15
col name for a40
col display_value for a50
select sid,name,display_value,ordinal from v$spparameter where isspecified='TRUE' order by name,ordinal,sid;
col con_name for a20
col name for a30
col value for a30
col display_value for a30
col default_value for a30
select con_id_to_con_name(a.con_id) con_name,inst_id,name,value,display_value,default_value
from gv$system_parameter a where (ismodified='MODIFIED' or isdefault='FALSE') order by con_id,name,inst_id;
5)监控PDB内存使用
十几个 PDB 跑在一个 CDB 里,谁内存泄露谁搞事,以前全靠猜。用V$RSRCPDBMETRIC视图,精确到每个 PDB 的 SGA、PGA、Buffer Cache 使用量。还有历史视图可以回溯,排查间歇性问题神器。
# 两个重要视图:V$RSRCPDBMETRIC、V$RSRCPDBMETRIC_HISTORY
COLUMN PDB_NAME FORMAT A10
col BUFFER_CACHE_BYTES for 999999999999999999
col SHARED_POOL_BYTES for 99999999999999
col SGA_BYTES for 99999999999999
col PGA_BYTES for 99999999999999
SELECT r.CON_ID, p.PDB_NAME, r.SGA_BYTES, r.PGA_BYTES, r.BUFFER_CACHE_BYTES, r.SHARED_POOL_BYTES FROM V$RSRCPDBMETRIC r, CDB_PDBS p WHERE r.CON_ID = p.CON_ID;
•SGA_BYTES - PDB's current SGA usage
•BUFFER_CACHE_BYTES - PDB's current buffer cache usage
•SHARED_POOL_BYTES - PDB's current shared pool usage
•PGA_BYTES - PDB's current PGA usage
6)监控PDB实时IO使用
IO 打满是多租户最常见的性能问题。一个 PDB 跑个全表扫描,全库都卡。这个语句看每个 PDB 最近 1 分钟的 IOPS、吞吐量和延迟。如果avg_io_throttle值高,说明已经被限流了,该调配额或者优化 SQL 了。
SET LINESIZE 180
COLUMN pdb_name FORMAT A10
COLUMN begin_time FORMAT A26
COLUMN end_time FORMAT A26
ALTER SESSION SET NLS_DATE_FORMAT='DD-MON-YYYY HH24:MI:SS';
ALTER SESSION SET NLS_TIMESTAMP_FORMAT='DD-MON-YYYY HH24:MI:SS.FF';
-- 每个PDB最后样本
SELECT r.con_id,
p.pdb_name,
r.begin_time,
r.end_time,
r.iops,
r.iombps,
r.iops_throttle_exempt,
r.iombps_throttle_exempt,
r.avg_io_throttle
FROM v$rsrcpdbmetric r,
cdb_pdbs p
WHERE r.con_id = p.con_id
ORDER BY p.pdb_name;
今天先分享这些日常最常用的。有什么补充或者踩过的奇葩坑,评论区聊聊。