美文网首页
数据库_其他

数据库_其他

作者: 仁安天下 | 来源:发表于2019-11-30 10:41 被阅读0次

    七、其他

    1.数据库的主从复制

    主从复制的几种方式:

    同步复制:

    所谓的同步复制,意思是master的变化,必须等待slave-1,slave-2,...,slave-n完成后才能返回。 这样,显然不可取,也不是MySQL复制的默认设置。比如,在WEB前端页面上,用户增加了条记录,需要等待很长时间。

    异步复制:

    如同AJAX请求一样。master只需要完成自己的数据库操作即可。至于slaves是否收到二进制日志,是否完成操作,不用关心,MySQL的默认设置。

    半同步复制:

    master只保证slaves中的一个操作成功,就返回,其他slave不管。 这个功能,是由google为MySQL引入的。

    2.数据库主从复制分析的 7 个问题?

    问题1:master的写操作,slaves被动的进行一样的操作,保持数据一致性,那么slave是否可以主动的进行写操作?

    假设slave可以主动的进行写操作,slave又无法通知master,这样就导致了master和slave数据不一致了。因此slave不应该进行写操作,至少是slave上涉及到复制的数据库不可以写。实际上,这里已经揭示了读写分离的概念。

    问题2:主从复制中,可以有N个slave,可是这些slave又不能进行写操作,要他们干嘛?

    实现数据备份:
    类似于高可用的功能,一旦master挂了,可以让slave顶上去,同时slave提升为master。

    异地容灾:比如master在北京,地震挂了,那么在上海的slave还可以继续。
    主要用于实现scale out,分担负载,可以将读的任务分散到slaves上。
    【很可能的情况是,一个系统的读操作远远多于写操作,因此写操作发向master,读操作发向slaves进行操作】

    问题3:主从复制中有master,slave1,slave2,...等等这么多MySQL数据库,那比如一个JAVA WEB应用到底应该连接哪个数据库?

    我们在应用程序中可以这样,insert/delete/update这些更新数据库的操作,用connection(for master)进行操作,

    select用connection(for slaves)进行操作。那我们的应用程序还要完成怎么从slaves选择一个来执行select,例如使用简单的轮循算法。

    这样的话,相当于应用程序完成了SQL语句的路由,而且与MySQL的主从复制架构非常关联,一旦master挂了,某些slave挂了,那么应用程序就要修改了。能不能让应用程序与MySQL的主从复制架构没有什么太多关系呢?
    找一个组件,application program只需要与它打交道,用它来完成MySQL的代理,实现SQL语句的路由。
    MySQL proxy并不负责,怎么从众多的slaves挑一个?可以交给另一个组件(比如haproxy)来完成。

    这就是所谓的MySQL READ WRITE SPLITE,MySQL的读写分离。

    问题4:如果MySQL proxy , direct , master他们中的某些挂了怎么办?

    总统一般都会弄个副总统,以防不测。同样的,可以给这些关键的节点来个备份。

    问题5:当master的二进制日志每产生一个事件,都需要发往slave,如果我们有N个slave,那是发N次,还是只发一次?如果只发一次,发给了slave-1,那slave-2,slave-3,...它们怎么办?

    显 然,应该发N次。实际上,在MySQL master内部,维护N个线程,每一个线程负责将二进制日志文件发往对应的slave。master既要负责写操作,还的维护N个线程,负担会很重。可以这样,slave-1是master的从,slave-1又是slave-2,slave-3,...的主,同时slave-1不再负责select。 slave-1将master的复制线程的负担,转移到自己的身上。这就是所谓的多级复制的概念。

    问题6:当一个select发往MySQL proxy,可能这次由slave-2响应,下次由slave-3响应,这样的话,就无法利用查询缓存了。

    应该找一个共享式的缓存,比如memcache来解决。将slave-2,slave-3,...这些查询的结果都缓存至mamcache中。

    问题7:随着应用的日益增长,读操作很多,我们可以扩展slave,但是如果master满足不了写操作了,怎么办呢?

    scale on ?更好的服务器? 没有最好的,只有更好的,太贵了。。。
    scale out ? 主从复制架构已经满足不了。
    可以分库【垂直拆分】,分表【水平拆分】。

    3.mysql 高并发环境解决方案?

    MySQL 高并发环境解决方案: 分库 分表 分布式 增加二级缓存。。。。。

    需求分析:互联网单位 每天大量数据读取,写入,并发性高。

    现有解决方式:水平分库分表,由单点分布到多点数据库中,从而降低单点数据库压力。

    集群方案:解决DB宕机带来的单点DB不能访问问题。

    读写分离策略:极大限度提高了应用中Read数据的速度和并发量。无法解决高写入压力。

    4.数据库崩溃时事务的恢复机制(REDO日志和UNDO日志)?

    转载:MySQL REDO日志和UNDO日志

    Undo Log:

    Undo Log是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用了Undo Log来实现多版本并发控制(简称:MVCC)。

    事务的原子性(Atomicity)事务中的所有操作,要么全部完成,要么不做任何操作,不能只做部分操作。如果在执行的过程中发生了错误,要回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过。
    原理Undo Log的原理很简单,为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为UndoLog)。然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。

    之所以能同时保证原子性和持久化,是因为以下特点:

    更新数据前记录Undo log。
    为了保证持久性,必须将数据在事务提交前写到磁盘。只要事务成功提交,数据必然已经持久化。
    Undo log必须先于数据持久化到磁盘。如果在G,H之间系统崩溃,undo log是完整的, 可以用来回滚事务。
    如果在A-F之间系统崩溃,因为数据没有持久化到磁盘。所以磁盘上的数据还是保持在事务开始前的状态。

    缺陷:每个事务提交前将数据和Undo Log写入磁盘,这样会导致大量的磁盘IO,因此性能很低。
    如果能够将数据缓存一段时间,就能减少IO提高性能。但是这样就会丧失事务的持久性。因此引入了另外一种机制来实现持久化,即Redo Log。

    Redo Log:

    原理和Undo Log相反,Redo Log记录的是新数据的备份。在事务提交前,只要将Redo Log持久化即可,不需要将数据持久化。当系统崩溃时,虽然数据没有持久化,但是Redo Log已经持久化。系统可以根据Redo Log的内容,将所有数据恢复到最新的状态。
    脏读:
    事务a读取到事务B修改的数据,事务B回滚后,事务a所读到的数据为脏读
    (针对未提交数据)如果一个事务中对数据进行了更新,但事务还没有提交,另一个事务可以“看到”该事务没有提交的更新结果,这样造成的问题就是,如果第一个事务回滚,那么,第二个事务在此之前所“看到”的数据就是一笔脏数据。
    不可重复读:
    事务a在事务b修改之前读一条数据,在事务b修改后读同一条数据,这两条数据不同,称为不可重复读
    (针对其他提交前后,读取数据本身的对比)不可重复读取是指同一个事务在整个事务过程中对同一笔数据进行读取,每次读取结果都不同。如果事务1在事务2的更新操作之前读取一次数据,在事务2的更新操作之后再读取同一笔数据一次,两次结果是不同的,所以,Read Uncommitted也无法避免不可重复读取的问题。
    幻读:
    事务a在事务B新增(删除)前查询一条数据,在事务B新增(删除)后读一条数据,这两条数据不同,称为幻读
    (针对其他提交前后,读取数据条数的对比) 幻读是指同样一笔查询在整个事务过程中多次执行后,查询所得的结果集是不一样的。幻读针对的是多笔记录。在Read Uncommitted隔离级别下, 不管事务2的插入操作是否提交,事务1在插入操作之前和之后执行相同的查询,取得的结果集是不同的,所以,Read Uncommitted同样无法避免幻读的问题。

    相关文章

      网友评论

          本文标题:数据库_其他

          本文链接:https://www.haomeiwen.com/subject/pnxowctx.html