本文主要讲解“数据库管理员在SQL中的分析”。感兴趣的朋友不妨看看。本文介绍的方法简单、快速、实用。让边肖带你学习“SQL分析中的DBA”!
场景10-1010:一旦程序所在的主机出现故障,需要在新环境中重新部署程序,程序备份的作用就会体现出来。
其实我的程序连接的底层数据库是Oracle RAC架构,一组程序可以直接部署在RAC的另一个节点。由于之前程序使用的文件默认在/home/oracle下,而且这个目录下还有很多其他与程序无关的文件,比较混乱,所以现在考虑将程序组织到一个统一的目录下,作为一个整体打包,方便备份,出现故障时可以轻松快速的重新部署。
我把目录:/home/oracle/baby放在这里,按照当前版本号对程序进行打包备份,最后把备份好的包复制到NAS中保留。
1.1 统一放置目录:/home/oracle/baby
[Oracle @ jystdra 2 baby]$ pwd
/家庭/先知/婴儿
[Oracle @ jystdra 2 baby]$ ls-lrth
总计76K
-rw-r-r-1 raceloinstallation 36 dec 2209:47 D1 . SQL
-rw-r-r-1 raceloinstallation 71 dec 2209:47 i1 . SQL
-rw-r-r-1 raceloinstallation 91 dec 2209:47 I2 . SQL
-rw-r-r-1 raceloinstallation 59 dec 2209:47 u1 . SQL
-rw-r-r-1 raceloinstallation 199 dec 2209:47 v1 . SQL
-rw-r-r-1 raceloinstallation 218 dec 2209:47 v2 . SQL
-rw-r-r-1 raceloinstallation 396 dec 2209:47 v3 . SQL
-rw-r-r-1 raceloinstallation 465 dec 2209336047 v4 . SQL
-rw-r-r-1 raceloinstallation 132 dec 2209:47v _ estimate . SQL
-rwxr-xr-x1oracleoinstall 302 dec 2209:54 BabY _ delete . sh
-rwxr-xr-x1oracleoinstall 296 dec 2209:55 BabY _ insert . sh
-rwxr-xr-x1oracleoinstall 335 dec 2209:55 BabY _ insert _ DIY . sh
-rwxr-xr-x1oracleoinstall 545 dec 2209:56 BabY _ help . sh
-rwxr-xr-x1oracleoinstall 305 dec 2209:57 BabY _ update . sh
-rwxr-xr-x1oracleoinstall 293 dec 2209:57 BabY _ view . sh
-rwxr-xr-x1oracleoinstall 252 dec 2209:58 BabY _ view _ DIY . sh
-rw-r-r-1 raceloinstallation 244 dec 2213:30 bash _ profile
-rw-r-r-1 raceloinstallation 273 dec 2609:10 b
ackup_exp_t_baby.sh
-rw-r--r-- 1 oracle oinstall 154 Dec 26 09:53 readme
[oracle@jystdrac2 baby]$ cd ..
1.2 将程序按照当前版本号进行打包备份
[oracle@jystdrac2 ~]$ tar -zcvf baby_v2.02.tar.gz baby/ baby/ baby/readme baby/u1.sql baby/v4.sql baby/baby_view_diy.sh baby/d1.sql baby/v3.sql baby/baby_update.sh baby/v2.sql baby/v_estimate.sql baby/i1.sql baby/bash_profile baby/baby_insert_diy.sh baby/baby_insert.sh baby/i2.sql baby/v1.sql baby/baby_help.sh baby/baby_view.sh baby/baby_delete.sh baby/backup_exp_t_baby.sh [oracle@jystdrac2 ~]$ ls -lrth baby_v2.02.tar.gz -rw-r--r-- 1 501 1000 1.9K Dec 26 11:46 baby_v2.02.tar.gz
1.3 最后拷贝备份的程序包到NAS留存
[oracle@jystdrac2 ~]$ cp baby_v2.02.tar.gz /public/backup/
2.数据备份
场景:上面已经做了程序备份,但出现故障时我们只恢复程序是不够的,还需要之前产生的业务数据。所以我们还需要业务数据的备份。
可以采用exp/expdp定时逻辑备份,因为我这里数据量很小,所以直接采用更简单的exp备份。
比如每天12点使用exp备份出当前表t_baby的数据:
设置crontab定时任务:
[oracle@jystdrac2 ~]$ crontab -l 0 12 * * * /bin/sh /home/oracle/baby/backup_exp_t_baby.sh
exp备份脚本:
[oracle@jystdrac2 ~]$ cat /home/oracle/baby/backup_exp_t_baby.sh backupdate=`date +%Y%m%d` export ORACLE_SID=demo2 export ORACLE_BASE=/opt/app/oracle export ORACLE_HOME=/opt/app/oracle/product/11.2.0/dbhome_1 export PATH=$PATH:$ORACLE_HOME/bin exp test/test tables=t_baby file=/public/backup/t_baby_$backupdate.dmp log=/public/backup/t_baby_$backupdate.log
备份出的文件类似这样:
[oracle@jystdrac2 backup]$ ls -lrth t_baby* -rw-rw-rw- 1 501 1000 626 Dec 26 12:00 t_baby_20191226.log -rw-rw-rw- 1 501 1000 16K Dec 26 12:00 t_baby_20191226.dmp
3.数据实时同步
场景:如果只有上面步骤的定时逻辑备份,其实还是无法满足完全的数据恢复的。
比如今天中午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 ~]# date Sun Dec 22 08:48:51 CST 2019 [root@jystdrac1 ~]# ntpdate ntp2.aliyun.com 22 Dec 08:52:31 ntpdate[24481]: step time server 203.107.6.88 offset 206.232030 sec [root@jystdrac1 ~]# date Sun Dec 22 08:52:35 CST 2019 --使用crontab定时,每小时与阿里云时间服务器同步一次,同步日志追加到/tmp/ntpdate.log日志文件 crontab -l 0 * * * * ntpdate ntp2.aliyun.com >> /tmp/ntpdate.log
当然,这里其实还可以设置NTP微调(-x)模式,保证RAC稳定性不受其调整的影响。
4.2 数据一致性问题
这个也可以说是程序设计时的bug。
现象:当前程序连接的数据库底层是单实例,或始终在RAC的同一个节点上运行,就不会有任何问题;但如果在RAC的两个节点交叉运行插入数据,序列就会出现问题导致计算结果产生讹误。
先称之为是RAC环境下sequence的问题解决:
比如:在节点1插入记录,ID为235,再到节点2插入记录,ID却为192.
[oracle@jystdrac2 ~]$ i Insert a row using current time: 1 row created. Commit complete. View Today's Result: ID FEED_TIME L LAG(min) LAG(h) ---------- ----------- - ---------- ---------- 192 12-26 18:21 N 5689 94.82 227 12-26 02:22 N 225 3.75 228 12-26 04:48 N 146 2.43 229 12-26 07:31 N 164 2.73 230 12-26 10:02 N 151 2.51 231 12-26 11:49 N 107 1.79 232 12-26 14:10 N 141 2.34 233 12-26 17:38 N 208 3.47 234 12-26 18:18 N 41 .68 235 12-26 18:19 N 0 .01 10 rows selected.
可以看到在节点2后插入的记录ID值反而小,导致程序本身间隔计算也出现了讹误,明显这样是有问题的。
其实问题也非常明显,实例1和实例2获取s1的sequence是不连续的,分别在两个实例上查询:
--实例1: test@DEMO> select s1.nextval from dual; NEXTVAL ---------- 239 --实例2: test@DEMO> select s1.nextval from dual; NEXTVAL ---------- 193
查询下sequence的创建语句:
test@DEMO> select dbms_metadata.get_ddl('SEQUENCE','S1') from dual; DBMS_METADATA.GET_DDL('SEQUENCE','S1') -------------------------------------------------------------------------------- CREATE SEQUENCE "TEST"."S1" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 STA RT WITH 241 CACHE 20 NOORDER NOCYCLE
可以看到序列默认是NOORDER,如果设为ORDER,测试反复在两个实例上交叉读序列的nextval,都能保证序列值是顺序的,就不会再出现最初的情况。
所以解决方案就是重建sequence s1,修改为ORDER。
drop SEQUENCE s1; CREATE SEQUENCE s1 MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 261 CACHE 20 ORDER NOCYCLE;
再次验证(select s1.nextval from dual;),确认此时序列是有序的:
--实例1: test@DEMO> select s1.nextval from dual; NEXTVAL ---------- 261 --实例2: test@DEMO> select s1.nextval from dual; NEXTVAL ---------- 262
但还需要注意如果将序列改为ORDER,在实际业务压力大时很可能会造成严重性能问题,这估计也是不加任何参数创建的sequence默认就是NOORDER的原因。
到此,相信大家对“分析SQL中的DBA”有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/68682.html