当前位置:首页 » 数据仓库 » 数据库并发时间段
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

数据库并发时间段

发布时间: 2023-01-07 13:06:56

‘壹’ 数据库死锁,并发问题

补充楼主:
其实我没什么经验,只不过是了解一些基础的东西罢了。
一楼的 一朵瘩红花 实际经验很丰富,你可以向她咨询一下。

你问的问题挺好得。三个概念紧密联系在一起。
这样说吧:并发的几个事务同时发生,不加锁控制的话数据就会乱套了,而加了锁后,又是并发访问会出现死锁,所以就会出现避免死锁的一些措施。
首先谈并发:理论指的是在一段时间同时对某件事进行操作。 注意精度问题,修改数据库是在一段时间内操作,不是在某个时刻,而日志则会从 时刻 开始记录你的操作。

造成死锁的原因是为了防止 不同的用户同时间(不是时刻)都对某个数据修改,造成访问不一致的问题。
比如你读了数据库的一个数据然后把它修改了并存回去,是需要时间的(假如是student表中的有个grade属性,你改了一条记录的一个值)在这个过程当中,有人又访问了数据库并且恰恰访问的是存回去之前的数据,然后他要进行操作,过了一段时间,此时你已经存回去了数据。会发现原来的数据被改动了。这时数据就乱套了。(专业术语叫读脏数据,其实还有很多其他类似这种导致前后数据不一致的问题)所以为了限定这种操作,数据库设计了-----锁---来锁定这种操作。就是你正在操作某个数据的时候----通常之前会先锁定这个数据,这样别人就不能对此数据操作了(严格来说就是只能读,不能改),必须等你操作完才能对此数据修改等操作,这就在一定程度上避免了前后操作数据不一致的问题。

但是有了锁后,新问题出现了,就是死锁:

简单解释死锁:进程A等待进程B释放他的资源,B又等待A释放他的资源,这样就互相等待就形成死锁

官方解释死锁
死锁,根本原因在于对共享存储区的访问。在数据库中也一样,如果需要“修改”一条数据,首先数据库管理系统会在上面加锁,以保证在同一时间只有一个事务能进行修改操作。锁有多种实现方式,比如意向锁,共享-排他锁,锁表,树形协议,时间戳协议等等。锁还有多种粒度,比如可以在表上加锁,也可以在记录上加锁。

在并发控制中,锁是非常重要的。
至于在Oracle还是别的数据库管理系统中,死锁产生的原因没有不同,不同的顶多是锁的实现或者死锁的恢复等罢了

再来说说事务:
事务简单来说就是 一系列的对数据库的操作揉在一起,要么同时完成,要么就都不完成。
比如---你要取钱的过程就可以当成是一个小的事务: 插卡,输入取钱金额,取走钱,拿出来卡。此过程缺一不可。把所有这些过程细节封装起来就成为一个事务。
以oracle数据库为例:
一个事务(你可以认为是一系列业务的操作)起始于dml语句(insert、update、delete)
即一条dml语句就做为一个事务的起始,然后根据业务需要,进行其他的dml操作都算是事务的一部分。
最后碰到commit。或者rollback,或者其他意外什么的都算作一个事务的结束。
整个过程就是一个事务。
事务的理论解释就是那四个什么特性:什么原子性、一致性、隔离性和持久性
简称ACID

剩下的:数据库是建立在操作系统之上的一个层次。
你问的是数据库的存储机制??工作机制??还是什么的??
数据库就是存数据的。数据库管理系统是 对存的数据进行高效率的管理
大的结构分物理数据跟逻辑数据。
物理数据就是数据在存储设备上的存储方式,什么物理联系,物理结构,物理记录等 术语。
逻辑数据就是程序员和用户看到的数据形式。什么逻辑联系,逻辑结构==同上
数据库管理类系统就是把这些逻辑跟物理相互转换。 好比你输入的叫逻辑数据存储在磁盘上叫物理数据。等等。

废话了一堆,也不知道回答对你的问题没~~

‘贰’ 如何处理数据库并发问题

想要知道如何处理数据并发,自然需要先了解数据并发。

什么是数据并发操作呢?
就是同一时间内,不同的线程同时对一条数据进行读写操作。

在互联网时代,一个系统常常有很多人在使用,因此就可能出现高并发的现象,也就是不同的用户同时对一条数据进行操作,如果没有有效的处理,自然就会出现数据的异常。而最常见的一种数据并发的场景就是电商中的秒杀,成千上万个用户对在极端的时间内,抢购一个商品。针对这种场景,商品的库存就是一个需要控制的数据,而多个用户对在同一时间对库存进行重写,一个不小心就可能出现超卖的情况。

针对这种情况,我们如何有效的处理数据并发呢?

第一种方案、数据库锁
从锁的基本属性来说,可以分为两种:一种是共享锁(S),一种是排它锁(X)。在Mysql的数据库中,是有四种隔离级别的,会在读写的时候,自动的使用这两种锁,防止数据出现混乱。

这四种隔离级别分别是:

读未提交(Read Uncommitted)
读提交(Read Committed)
可重复读(Repeated Read)
串行化(Serializable)
当然,不同的隔离级别,效率也是不同的,对于数据的一致性保证也就有不同的结果。而这些可能出现的又有哪些呢?

脏读(dirty read)

当事务与事务之间没有任何隔离的时候,就可能会出现脏读。例如:商家想看看所有的订单有哪些,这时,用户A提交了一个订单,但事务还没提交,商家却看到了这个订单。而这时就会出现一种问题,当商家去操作这个订单时,可能用户A的订单由于部分问题,导致数据回滚,事务没有提交,这时商家的操作就会失去目标。

不可重复读(unrepeatable read)

一个事务中,两次读操作出来的同一条数据值不同,就是不可重复读。

例如:我们有一个事务A,需要去查询一下商品库存,然后做扣减,这时,事务B操作了这个商品,扣减了一部分库存,当事务A再次去查询商品库存的时候,发现这一次的结果和上次不同了,这就是不可重复读。

幻读(phantom problem)

一个事务中,两次读操作出来的结果集不同,就是幻读。

例如:一个事务A,去查询现在已经支付的订单有哪些,得到了一个结果集。这时,事务B新提交了一个订单,当事务A再次去查询时,就会出现,两次得到的结果集不同的情况,也就是幻读了。

那针对这些结果,不同的隔离级别可以干什么呢?

“读未提(Read Uncommitted)”能预防啥?啥都预防不了。

“读提交(Read Committed)”能预防啥?使用“快照读(Snapshot Read)”方式,避免“脏读”,但是可能出现“不可重复读”和“幻读”。

“可重复读(Repeated Red)”能预防啥?使用“快照读(Snapshot Read)”方式,锁住被读取记录,避免出现“脏读”、“不可重复读”,但是可能出现“幻读”。

“串行化(Serializable)”能预防啥?有效避免“脏读”、“不可重复读”、“幻读”,不过运行效率奇差。

好了,锁说完了,但是,我们的数据库锁,并不能有效的解决并发的问题,只是尽可能保证数据的一致性,当并发量特别大时,数据库还是容易扛不住。那解决数据并发的另一个手段就是,尽可能的提高处理的速度。

因为数据的IO要提升难度比较大,那么通过其他的方式,对数据进行处理,减少数据库的IO,就是提高并发能力的有效手段了。

最有效的一种方式就是:缓存
想要减少并发出现的概率,那么读写的效率越高,读写的执行时间越短,自然数据并发的可能性就变小了,并发性能也有提高了。

还是用刚才的秒杀举例,我们为的就是保证库存的数据不出错,卖出一个商品,减一个库存,那么,我们就可以将库存放在内存中进行处理。这样,就能够保证库存有序的及时扣减,并且不出现问题。这样,我们的数据库的写操作也变少了,执行效率也就大大提高了。

当然,常用的分布式缓存方式有:Redis和Memcache,Redis可以持久化到硬盘,而Memcache不行,应该怎么选择,就看具体的使用场景了。

当然,缓存毕竟使用的范围有限,很多的数据我们还是必须持久化到硬盘中,那我们就需要提高数据库的IO能力,这样避免一个线程执行时间太长,造成线程的阻塞。

那么,读写分离就是另一种有效的方式了
当我们的写成为了瓶颈的时候,读写分离就是一种可以选择的方式了。

我们的读库就只需要执行读,写库就只需要执行写,把读的压力从主库中分离出去,让主库的资源只是用来保证写的效率,从而提高写操作的性能。

‘叁’ 在数据库中如何将时间段做为字段保存

你这个只能用字符串类型保存!!
建议你用两个datetime字段来分别保存起始时间和结束时间!!

‘肆’ 怎么提高数据库高峰时访问的并发能力

1:首先需要有非常良好的网络带宽,若有上万人同时录入数据的普通的Web信息管理系统,至少需要10M左右的网络带宽,而且网通、电信的主干网都有接入比较好,否则全国各地的网络情况都不太一样,有的城市录入数据时可能会遇到网络非常缓慢的情况,甚至到无法忍受的程度。

2:须有一台牛X的Web服务器 + 一台牛X的数据库服务器(备注接近顶配的奢侈硬件服务器非个人PC),由于是需要录入1000万条以上数据,最好采用Oracle数据库比较理想一些,经得起考验一些。

3:需要进行适当的内存缓存优化策略,不能所有的数据库都依靠SQL数据库的方式把压力放在数据库服务器上,尽量多使用内存的方式处理数据。

4:需要一个牛X的,经得起考验的数据库访问层,因为每秒都有可能成千上万的人在访问,若是质量不良好的数据库访问组件、或者不稳定的数据库访问组件,更容易导致系统崩溃、或者占用非常庞大的内存,最后容易导致整个系统的崩溃。

5:需要优化分页存取数据功能,应为有可能会有1000万条数据,若分页读取数据的功能没能优化到最高,也很容易导致系统的崩溃,因为上万人万一在同一时间,或者接近同一时间点了查询某页数据时,那系统就真崩溃了,分页存取数据一定需要做到极致才可以。

6:需要进行数据库索引优化,有索引和没索引的性能差距有时候会是100倍,大数据量时可能会有1000倍都有可能,数据库索引优化到极致了更容易得到运行顺畅的信息管理系统。

7:严谨高效的数据库事务处理,由于高并发,并且有些单据是需要同时写入多个表,需要保证数据库的一致性,要么全部成功,要么全部失败重新录入数据,所以需要一个高效的数据库事务处理机制的配合。

8:所有的系统的操作日志、异常信息都需要完整的记录下来,当系统发生一些故障时,可以快速排查问题,对正确诊断系统发生的故障的原因做分析参考用。

9:需要经常检测系统的各项指标、例如各服务器的内存使用情况、CPU使用情况、网络带宽使用情况,高峰时的各个参数是什么情况、系统不繁忙时的情况等,若服务器快承受不了压力了,就得马上增加负载均衡的服务器,网络带宽不够了需要增加等等,总不能等系统崩溃了再去做这些事情。

10:每个页面的HTML、JS都进行优化,若某个页面多余发了100个字符的垃圾HTML代码,那1万人每天获得100次,那得占用多少网络带宽,100×100×1万个字符的多余HTML被网络上传输了,要知道接入主干网的网络资源是多么宝贵,费用是多么昂贵。

11:HTML、JS等都可以考虑用压缩模式传输,那样网络传输效率会更高一些。

12:由于全国各地上万人,会有各种各样的人,这些人也未必全是好人,可能某些人心情不好,或者其他什么的,可能就会攻击我们的软件系统破坏数据,这些也可能是由于好奇心导致的,所以系统需要有严格的权限管理控制,不应该进入的页面绝对不能进入,不应该看的数据绝对不让看,不能操作的功能绝对不让多操作,一方面防止没必要的多余的麻烦,另一方面也可以减少系统被攻击破坏的可能性。

‘伍’ 如何处理mysql数据库并发更新问题

现象

Sysbench对MySQL进行压测, 并发数过大(>5k)时, Sysbench建立连接的步骤会超时.

猜想

猜想: 直觉上这很简单, Sysbench每建立一个连接, 都要消耗一个线程, 资源消耗过大导致超时.

验证: 修改Sysbench源码, 调大超时时间, 仍然会发生超时.

检查环境

猜想失败, 回到常规的环境检查:

  • MySQL error log 未见异常.

  • syslog 未见异常.

  • tcpmp 观察网络包未见异常, 连接能完成正常的三次握手; 只观察到在出问题的连接中, 有一部分的TCP握手的第一个SYN包发生了重传, 另一部分没有发生重传.

  • 自己写一个简单的并发发生器, 替换sysbench, 可重现场景. 排除sysbench的影响

  • 猜想2

    怀疑 MySQL 在应用层因为某种原因, 没有发送握手包, 比如卡在某一个流程上:

  • 检查MySQL堆栈未见异常, 仿佛MySQL在应用层没有看到新连接进入.

  • 通过strace检查MySQL, 发现accept()调用确实没有感知到新连接.

  • 怀疑是OS的原因, Google之, 得到参考文档:A TCP “stuck” connection mystery【http://www.evanjones.ca/tcp-stuck-connection-mystery.html】

    分析

    参考文档中的现象跟目前的状况很类似, 简述如下:

    正常的TCP连接流程:

  • Client 向 Server 发起连接请求, 发送SYN.

  • Server 预留连接资源, 向 Client 回复SYN-ACK.

  • Client 向 Server 回复ACK.

  • Server 收到 ACK, 连接建立.

  • 在业务层上, Client和Server间进行通讯.

  • 当发生类似SYN-flood的现象时, TCP连接的流程会使用SYN-cookie, 变为:

  • Client 向 Server 发起连接请求, 发送SYN.

  • Server 不预留连接资源, 向 Client 回复SYN-ACK, 包中附带有签名A.

  • Client 向 Server 回复ACK, 附带 f(签名A) (对签名进行运算的结果).

  • Server 验证签名, 分配连接资源, 连接建立.

  • 在业务层上, Client和Server间进行通讯.

  • 当启用SYN-cookie时, 第3步的ACK包因为某种原因丢失, 那么:

  • 从Client的视角, 连接已经建立.

  • 从Server的视角, 连接并不存在, 既没有建立, 也没有”即将建立” (若不启用SYN-cookie, Server会知道某个连接”即将建立”)

  • 发生这种情况时:

  • 若业务层的第一个包应是从 Client 发往 Server, 则会进行重发或抛出连接错误

  • 若业务层的第一个包应是从 Server 发往 Client的, Server不会发出第一个包. MySQL的故障就属于这种情况.

  • TCP握手的第三步ACK包为什么丢失

    参考文档中, 对于TCP握手的第三步ACK包的丢失原因, 描述为:

  • Some of these packets get lost because some buffer somewhere overflows.

  • 我们可以通过Systemtap进一步探究原因.通过一个简单的脚本:

  • probe kernel.function("cookie_v4_check").return

  • {

  • source_port = @cast($skb->head + $skb->transport_header, "struct tcphdr")->source

  • printf("source=%d, return=%d ",readable_port(source_port), $return)

  • }

  • function readable_port(port) {

  • return (port & ((1<<9)-1)) << 8 | (port >> 8)

  • }

  • 观察结果, 可以确认cookie_v4_check(syn cookie机制进行包签名检查的函数)会返回 NULL(0). 即验证是由于syn cookie验证不通过, 导致TCP握手的第三步ACK包不被接受.

    之后就是对其中不同条件进行观察, 看看是哪个条件不通过. 最终原因是accept队列满(sk_acceptq_is_full):

  • static inline bool sk_acceptq_is_full(const struct sock *sk){ return sk->sk_ack_backlog > sk- >sk_max_ack_backlog;}

  • 恢复故障与日志的正关联

    在故障处理的一开始, 我们就检查了syslog, 结论是未见异常.

    当整个故障分析完成, 得知了故障与syn cookie有关, 回头看syslog, 里面是有相关的信息, 只是和故障发生的时间不匹配, 没有正关联, 因此被忽略.

    检查Linux源码:

  • if (!queue->synflood_warned &&

  • sysctl_tcp_syncookies != 2 &&

  • xchg(&queue->synflood_warned, 1) == 0)

  • pr_info("%s: Possible SYN flooding on port %d. %s.

  • Check SNMP counters. ",

  • proto, ntohs(tcp_hdr(skb)->dest), msg);

  • 可以看到日志受到了抑制, 因此日志与故障的正关联被破坏.

    粗看源码, 每个listen socket只会发送一次告警日志, 要获得日志与故障的正关联, 必须每次测试重启MySQL.

    解决方案

    这种故障一旦形成, 难以检测; 系统日志中只会出现一次, 在下次重启MySQL之前就不会再出现了; Client如果没有合适的超时机制, 万劫不复.

    解决方案:
    1. 修改MySQL的协议, 让Client先发握手包. 显然不现实.
    2. 关闭syn_cookie. 有安全的人又要跳出来了.
    3. 或者调高syn_cookie的触发条件 (syn backlog长度). 降低系统对syn flood的敏感度, 使之可以容忍业务的syn波动.

    有多个系统参数混合影响syn backlog长度, 参看【http://blog.bbelboer.com/2012/04/09/syn-cookies.html】

    下图为精华总结

‘陆’ 如何处理大量数据并发操作

处理大量数据并发操作可以采用如下几种方法:

1.使用缓存:使用程序直接保存到内存中。或者使用缓存框架: 用一个特定的类型值来保存,以区别空数据和未缓存的两种状态。

2.数据库优化:表结构优化;SQL语句优化,语法优化和处理逻辑优化;分区;分表;索引优化;使用存储过程代替直接操作。

3.分离活跃数据:可以分为活跃用户和不活跃用户。

4.批量读取和延迟修改: 高并发情况可以将多个查询请求合并到一个。高并发且频繁修改的可以暂存缓存中。

5.读写分离: 数据库服务器配置多个,配置主从数据库。写用主数据库,读用从数据库。

6.分布式数据库: 将不同的表存放到不同的数据库中,然后再放到不同的服务器中。

7.NoSql和Hadoop: NoSql,not only SQL。没有关系型数据库那么多限制,比较灵活高效。Hadoop,将一个表中的数据分层多块,保存到多个节点(分布式)。每一块数据都有多个节点保存(集群)。集群可以并行处理相同的数据,还可以保证数据的完整性。

拓展资料:

大数据(big data),指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。

在维克托·迈尔-舍恩伯格及肯尼斯·库克耶编写的《大数据时代》中大数据指不用随机分析法(抽样调查)这样捷径,而采用所有数据进行分析处理。大数据的5V特点(IBM提出):Volume(大量)、Velocity(高速)、Variety(多样)、Value(低价值密度)、Veracity(真实性)。

‘柒’ 数据库原理并发控制问题

并发(concurrent)和并行(parallel)这两个概念,在数据库系统的资料中经常出现,然而有关它们的定义和区别却没有明确的说法。这里,我们根据这两个概念在资料中的使用,对它们的不同做一个说明。

并发是指多个任务的同时执行,任务与任务之间没有联系。由于数据库系统要同时为许多用户提供服务,每个用户都可以发出自己的访问请求,一个请求就是一个任务。在一个时间点,数据库系统可能要同时处理多个任务。因此,数据库系统一定要具备并发处理能力。

并行是指将一个任务划分为多个子任务,这些子任务同时执行。在所有子任务处理完成后,将它们的结果进行合并,就得到该任务的最终处理结果。在数据库系统中,如果要执行一个大的数据查询,为了提高速度、降低响应时间,用户可以通过系统配置或者在命令中,要求对该大数据量查询进行并行处理,将该查询划分成多个子查询。这些子查询同时执行,最后系统将所有子查询的处理结果进行合并,作为该查询处理的最终结果。现有的大型数据库系统都支持并行处理。

需要说明的是,并发和并行与数据库系统采用多进程还是多线程体系结构无关。对采用多进程结构的数据库系统,所有的任务、子任务通过进程来处理;而对采用多线程结构的数据库系统,这些工作是由线程来完成。

数据库系统的并发控制,涉及到任务的调度、数据的一致性及可靠性等,而数据库系统的并行处理,主要涉及任务的处理速度、系统性能等方面。