使用SQL计算宝宝每次吃奶的时间间隔(数据保障篇)
目前程序从功能上其实已经完全满足客户(当然我这里的客户都是指媳妇儿_)需求,具体可参考:
那么本篇 使用SQL计算宝宝每次吃奶的时间间隔 - Part3:保障数据安全 存在的意义在哪呢?
原因很简单,就是因为我们作为技术人,实际需要考虑的要更多。比如本篇从数据保障层面,我们必须要考虑数据的一致性和安全性等。而且我们要很清楚,这些需求并不是客户不关注不需要,很可能只是因为客户并不知道可能会出现什么问题,不知道如果一旦出现硬件损坏、各类故障导致数据损坏或出现讹误时,我们目前的情况是恢复不了的,到时就只能被说成是技术差,甚至连带背各种锅。在这样的场景下,技术人再去狡辩说客户开始也压根没提这些安全性的数据保障需求啊,是没有人会站在技术这一边的,因为这些客户考虑不到的,恰恰是需要你来主动去提出去建议去实施的,这也是体现一位技术人专业性的关键所在。
下面以几个维度来展开说明:
1.程序备份
场景:一旦程序所在主机故障,需要在新环境下重新部署程序时,程序备份的作用就体现出来了。
其实我这里程序所连接的底层数据库是Oracle RAC架构,可直接在RAC另一个节点部署一套程序。因为之前程序使用的文件默认在/home/oracle下,该目录还有很多其他与程序无关的文件,比较混乱,现考虑将程序整理到统一目录下整体打包,便于备份,遇到故障也可以方便快速重新部署。
我这里统一放置目录:/home/oracle/baby,并将程序按照当前版本号进行打包备份,最后拷贝备份的程序包到NAS留存。
1.1 统一放置目录:/home/oracle/baby
[oracle@jystdrac2 baby]$ pwd
/home/oracle/baby
[oracle@jystdrac2 baby]$ ls -lrth
total 76K
-rw-r--r-- 1 oracle oinstall 36 Dec 22 09:47 d1.sql
-rw-r--r-- 1 oracle oinstall 71 Dec 22 09:47 i1.sql
-rw-r--r-- 1 oracle oinstall 91 Dec 22 09:47 i2.sql
-rw-r--r-- 1 oracle oinstall 59 Dec 22 09:47 u1.sql
-rw-r--r-- 1 oracle oinstall 199 Dec 22 09:47 v1.sql
-rw-r--r-- 1 oracle oinstall 218 Dec 22 09:47 v2.sql
-rw-r--r-- 1 oracle oinstall 396 Dec 22 09:47 v3.sql
-rw-r--r-- 1 oracle oinstall 465 Dec 22 09:47 v4.sql
-rw-r--r-- 1 oracle oinstall 132 Dec 22 09:47 v_estimate.sql
-rwxr-xr-x 1 oracle oinstall 302 Dec 22 09:54 baby_delete.sh
-rwxr-xr-x 1 oracle oinstall 296 Dec 22 09:55 baby_insert.sh
-rwxr-xr-x 1 oracle oinstall 335 Dec 22 09:55 baby_insert_diy.sh
-rwxr-xr-x 1 oracle oinstall 545 Dec 22 09:56 baby_help.sh
-rwxr-xr-x 1 oracle oinstall 305 Dec 22 09:57 baby_update.sh
-rwxr-xr-x 1 oracle oinstall 293 Dec 22 09:57 baby_view.sh
-rwxr-xr-x 1 oracle oinstall 252 Dec 22 09:58 baby_view_diy.sh
-rw-r--r-- 1 oracle oinstall 244 Dec 22 13:30 bash_profile
-rw-r--r-- 1 oracle oinstall 273 Dec 26 09:10 backup_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环境搭建的部分我这里不再详细展开,如有问题,可参考之前的文章:
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计算宝宝每次吃奶的时间间隔(数据保障篇)的更多相关文章
- 使用SQL计算宝宝每次吃奶的时间间隔(续)
本文是<使用SQL计算宝宝每次吃奶的时间间隔>的续篇,因为我工作繁忙,时常不能及时帮助媳妇儿记录,为了让不懂数据库的媳妇儿也可以自己用手机熟练操作.我继续做了一些修正和封装: 1.给媳妇儿 ...
- 使用SQL计算宝宝每次吃奶的时间间隔
需求:媳妇儿最近担心宝宝的吃奶时间不够规律,网上说是正常平均3小时喂奶一次,让我记录下每次的吃奶时间,分析下实际是否偏差很大,好在下次去医院复查时反馈给医生. 此外,还要注意有时候哭闹要吃奶,而实际只 ...
- SQL 计算列
SQL计算列,可以解决一般标量计算(数学计算,如ColumnA*ColumnB)的问题,而子查询计算(如select sum(salary) from tableOther where id=’ABC ...
- sql计算经纬度得出最近距离的公式
sql计算经纬度得出最近距离的公式 //根据经纬度计算两点距离 mappoint //数据库已有字段,商家经纬度 实例:113.272148,23.147299 $lon = "" ...
- SQL计算时间差并排除周末
SQL计算时间差并排除周末 CREATE FUNCTION DI_FN_GET_WorkDay (@begin DATETIME , @end DATETIME ) RETURNS int BEGIN ...
- 【HANA系列】SAP HANA SQL计算两个日期的差值
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL计算两个 ...
- 【HANA系列】SAP HANA SQL计算某日期是当月的第几天
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL计算某日 ...
- 【HANA系列】SAP HANA SQL计算某日期是当年的第几天
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL计算某日 ...
- Java工作流引擎节点接收人设置“按自定义SQL计算”系列讲解
关键字: 驰骋工作流程快速开发平台 工作流程管理系统 工作流引擎 asp.net工作流引擎 java工作流引擎. 开发者表单 拖拽式表单 工作流系统CCBPM节点访问规则接收人规则 适配数据库: o ...
随机推荐
- 前后端分离构架 与 json ajax简介
前后端分离 传统开发方式 曾几何时,JSP和Servlet为Java带来了无限风光,一时间大红大紫,但随着互联网的不断发展,这样的开发方式逐渐显露其弊端,在移动互联网炙手可热的今天,应用程序对于后台服 ...
- java的并发
问题: 过程: 正常流程:记录生成:状态=1-->北京:状态 = 3,4,-->定时任务:状态=5--->结束 异常流程:一条待处理的的记录生成以后,马上被定时任务处理,加载到内存, ...
- 配置数据库属性validationQuery
配置数据库时,属性validationQuery默认值为“select 1”,对于oracle值应为“select 1 from dual” validationQuery属性:用来验证数据库连接的语 ...
- Git的基本使用 -- 远程仓库
SSH公钥 生成公钥 ssh-keygen -t rsa -C "xxx@xxx.com" 然后按三次回车 添加公钥 cat ~/.ssh/id_rsa.pub查看公钥 将生成的公 ...
- jvm(n):JVM面试
Jvm内存结构,一般是面试官对Java虚拟机这块考察的第一问. Java虚拟机的内存结构一般可以从线程共有和线程私有两部分起头作答,然后再详细说明各自的部分,类似树状结构的作答,好处就是思路清晰,面试 ...
- ASP.NET + MVC5 入门完整教程四---MVC 中使用扩展方法
https://blog.csdn.net/qq_21419015/article/details/80433640 1.示例项目准备1)项目创建新建一个项目,命名为LanguageFeatures ...
- SpringMVC项目使用elastic search搜索
项目需要,引入了elastic search(后续简称es),后面将介绍本地对es的安装,使用以及java连接es查询的整个过程. 1.es索引字段建立与修改,以curl新增一个索引字段示例 curl ...
- deepin linux 安装之后 引导错误 出现 grub>
deepin 安装之后 引导错误 ,,, 忙了一晚上 终于解决了 太辛苦了 不过明白了grub的工作原理也不亏,,,, 就是 整个过程满满的绝望 (哭 环境说明 华硕顽石4 笔记本 硬盘分区表GPT ...
- freopen函数的使用以及freopen与fopen的区别
freopen函数的使用:参见这篇博客https://www.cnblogs.com/moonlit/archive/2011/06/12/2078712.html 当我们求解acm题目时,通常在设计 ...
- Python 多任务(线程) day2 (2)
同步 1.概念 :同步就是协同步调,按预定的先后次序运行 互斥锁 当多个线程几乎同时修改某一共享数据的时候,需要运行同步控制,最简单的同步机制是引入互斥锁.某个线程要更改共享数据时,先将其锁定,此时资 ...