分析SQL中的DBA
本篇内容主要讲解“分析SQL中的DBA”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“分析SQL中的DBA”吧!
1.程序备份场景:一旦程序所在主机故障,需要在新环境下重新部署程序时,程序备份的作用就体现出来了。
其实我这里程序所连接的底层数据库是Oracle RAC架构,可直接在RAC另一个节点部署一套程序。因为之前程序使用的文件默认在/home/oracle下,该目录还有很多其他与程序无关的文件,比较混乱,现考虑将程序整理到统一目录下整体打包,便于备份,遇到故障也可以方便快速重新部署。
我这里统一放置目录:/home/oracle/baby,并将程序按照当前版本号进行打包备份,最后拷贝备份的程序包到NAS留存。
1.1 统一放置目录:/home/oracle/baby
[oracle@jystdrac2baby]$pwd/home/oracle/baby[oracle@jystdrac2baby]$ls-lrthtotal76K-rw-r--r--1oracleoinstall36Dec2209:47d1.sql-rw-r--r--1oracleoinstall71Dec2209:47i1.sql-rw-r--r--1oracleoinstall91Dec2209:47i2.sql-rw-r--r--1oracleoinstall59Dec2209:47u1.sql-rw-r--r--1oracleoinstall199Dec2209:47v1.sql-rw-r--r--1oracleoinstall218Dec2209:47v2.sql-rw-r--r--1oracleoinstall396Dec2209:47v3.sql-rw-r--r--1oracleoinstall465Dec2209:47v4.sql-rw-r--r--1oracleoinstall132Dec2209:47v_estimate.sql-rwxr-xr-x1oracleoinstall302Dec2209:54baby_delete.sh-rwxr-xr-x1oracleoinstall296Dec2209:55baby_insert.sh-rwxr-xr-x1oracleoinstall335Dec2209:55baby_insert_diy.sh-rwxr-xr-x1oracleoinstall545Dec2209:56baby_help.sh-rwxr-xr-x1oracleoinstall305Dec2209:57baby_update.sh-rwxr-xr-x1oracleoinstall293Dec2209:57baby_view.sh-rwxr-xr-x1oracleoinstall252Dec2209:58baby_view_diy.sh-rw-r--r--1oracleoinstall244Dec2213:30bash_profile-rw-r--r--1oracleoinstall273Dec2609:10backup_exp_t_baby.sh-rw-r--r--1oracleoinstall154Dec2609:53readme[oracle@jystdrac2baby]$cd..
1.2 将程序按照当前版本号进行打包备份
[oracle@jystdrac2~]$tar-zcvfbaby_v2.02.tar.gzbaby/baby/baby/readmebaby/u1.sqlbaby/v4.sqlbaby/baby_view_diy.shbaby/d1.sqlbaby/v3.sqlbaby/baby_update.shbaby/v2.sqlbaby/v_estimate.sqlbaby/i1.sqlbaby/bash_profilebaby/baby_insert_diy.shbaby/baby_insert.shbaby/i2.sqlbaby/v1.sqlbaby/baby_help.shbaby/baby_view.shbaby/baby_delete.shbaby/backup_exp_t_baby.sh[oracle@jystdrac2~]$ls-lrthbaby_v2.02.tar.gz-rw-r--r--150110001.9KDec2611:46baby_v2.02.tar.gz
1.3 最后拷贝备份的程序包到NAS留存
[oracle@jystdrac2~]$cpbaby_v2.02.tar.gz/public/backup/2.数据备份
场景:上面已经做了程序备份,但出现故障时我们只恢复程序是不够的,还需要之前产生的业务数据。所以我们还需要业务数据的备份。
可以采用exp/expdp定时逻辑备份,因为我这里数据量很小,所以直接采用更简单的exp备份。
比如每天12点使用exp备份出当前表t_baby的数据:
设置crontab定时任务:
[oracle@jystdrac2~]$crontab-l012***/bin/sh/home/oracle/baby/backup_exp_t_baby.sh
exp备份脚本:
[oracle@jystdrac2~]$cat/home/oracle/baby/backup_exp_t_baby.shbackupdate=`date+%Y%m%d`exportORACLE_SID=demo2exportORACLE_BASE=/opt/app/oracleexportORACLE_HOME=/opt/app/oracle/product/11.2.0/dbhome_1exportPATH=$PATH:$ORACLE_HOME/binexptest/testtables=t_babyfile=/public/backup/t_baby_$backupdate.dmplog=/public/backup/t_baby_$backupdate.log
备份出的文件类似这样:
[oracle@jystdrac2backup]$ls-lrtht_baby*-rw-rw-rw-15011000626Dec2612:00t_baby_20191226.log-rw-rw-rw-1501100016KDec2612:00t_baby_20191226.dmp3.数据实时同步
场景:如果只有上面步骤的定时逻辑备份,其实还是无法满足完全的数据恢复的。
比如今天中午12点做了备份,晚上18点出现了故障,数据丢失。通过逻辑备份只能恢复到今天中午12点的数据,而12点到18点之间的数据将会丢失。
如果采用物理RMAN备份呢?其实也同样存在这样的问题,因为日志归档并不是实时的,如果故障不可恢复,联机重做日志也丢失,RMAN也是不完全恢复到最近的归档日志,也同样会有丢失部分数据的风险。
那怎么办呢?如何进行数据实时同步到另外的环境呢?目前可以想到两种主流的解决方案:
1)数据库DG实时同步
2)数据表OGG同步
数据库DG实时同步是物理的方式,数据表OGG同步是逻辑的方式。
一般情况下,如果两个方案只能选择其一时,我们会强烈推荐客户选用物理方式的实时同步,因为逻辑方式按经验来看遇到的问题远比物理方式要高。
而在我这个场景下,数据量很小,其实完全可以二者都选择。
至于DG和OGG环境搭建的部分我这里不再详细展开,如有问题,可参考之前的文章:
模拟生产搭建Standby RAC实验环境(11.2.0.4 DG)
OGG学习笔记02-单向复制配置实例
4.已知问题解决在这个计算喂奶间隔的程序投入使用了一段时间后,还发现一些问题亟待解决:
4.1 系统时间不准确
系统运行几天后,操作系统的时间会和真实时间相差几分钟,这个暂时通过定时同步阿里云的NTP服务器来解决。
--使用ntpdate命令与阿里云时间服务器(ntp2.aliyun.com)同步[root@jystdrac1~]#dateSunDec2208:48:51CST2019[root@jystdrac1~]#ntpdatentp2.aliyun.com22Dec08:52:31ntpdate[24481]:steptimeserver203.107.6.88offset206.232030sec[root@jystdrac1~]#dateSunDec2208:52:35CST2019--使用crontab定时,每小时与阿里云时间服务器同步一次,同步日志追加到/tmp/ntpdate.log日志文件crontab-l0****ntpdatentp2.aliyun.com>>/tmp/ntpdate.log
当然,这里其实还可以设置NTP微调(-x)模式,保证RAC稳定性不受其调整的影响。
4.2 数据一致性问题
这个也可以说是程序设计时的bug。
现象:当前程序连接的数据库底层是单实例,或始终在RAC的同一个节点上运行,就不会有任何问题;但如果在RAC的两个节点交叉运行插入数据,序列就会出现问题导致计算结果产生讹误。
先称之为是RAC环境下sequence的问题解决:
比如:在节点1插入记录,ID为235,再到节点2插入记录,ID却为192.
[oracle@jystdrac2~]$iInsertarowusingcurrenttime:1rowcreated.Commitcomplete.ViewToday'sResult:IDFEED_TIMELLAG(min)LAG(h)------------------------------------------19212-2618:21N568994.8222712-2602:22N2253.7522812-2604:48N1462.4322912-2607:31N1642.7323012-2610:02N1512.5123112-2611:49N1071.7923212-2614:10N1412.3423312-2617:38N2083.4723412-2618:18N41.6823512-2618:19N0.0110rowsselected.
可以看到在节点2后插入的记录ID值反而小,导致程序本身间隔计算也出现了讹误,明显这样是有问题的。
其实问题也非常明显,实例1和实例2获取s1的sequence是不连续的,分别在两个实例上查询:
--实例1:test@DEMO>selects1.nextvalfromdual;NEXTVAL----------239--实例2:test@DEMO>selects1.nextvalfromdual;NEXTVAL----------193
查询下sequence的创建语句:
test@DEMO>selectdbms_metadata.get_ddl('SEQUENCE','S1')fromdual;DBMS_METADATA.GET_DDL('SEQUENCE','S1')--------------------------------------------------------------------------------CREATESEQUENCE"TEST"."S1"MINVALUE1MAXVALUE9999999999999999999999999999INCREMENTBY1STARTWITH241CACHE20NOORDERNOCYCLE
可以看到序列默认是NOORDER,如果设为ORDER,测试反复在两个实例上交叉读序列的nextval,都能保证序列值是顺序的,就不会再出现最初的情况。
所以解决方案就是重建sequence s1,修改为ORDER。
dropSEQUENCEs1;CREATESEQUENCEs1MINVALUE1MAXVALUE9999999999999999999999999999INCREMENTBY1STARTWITH261CACHE20ORDERNOCYCLE;
再次验证(select s1.nextval from dual;),确认此时序列是有序的:
--实例1:test@DEMO>selects1.nextvalfromdual;NEXTVAL----------261--实例2:test@DEMO>selects1.nextvalfromdual;NEXTVAL----------262
但还需要注意如果将序列改为ORDER,在实际业务压力大时很可能会造成严重性能问题,这估计也是不加任何参数创建的sequence默认就是NOORDER的原因。
到此,相信大家对“分析SQL中的DBA”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。