• [问题求助] 为什么频繁更新的列不适合使用索引?
    为什么频繁更新的列不适合使用索引?
  • [问题求助] 根据时间点恢复的需要那些备份去恢复?某天的几点几分?增量转储到obs的增量文件,都包含那些信息?
    根据时间点恢复的需要那些备份去恢复?某天的几点几分?增量转储到obs的增量文件,都包含那些信息?
  • [问题求助] mysql 大事务会产生哪些影响? 1)前一张表在做update 同时做了ddl动作会产生什么现象?对后续操作影响吗?
    mysql 大事务会产生哪些影响?     1)前一张表在做update 同时做了ddl动作会产生什么现象?对后续操作影响吗?
  • [问题求助] 大表变更表结构,怎么考虑、评估,关注哪些指标? 大表可以直接做ddl吗?
    大表变更表结构,怎么考虑、评估,关注哪些指标? 大表可以直接做ddl吗?
  • [问题求助] 如果使用可用性优先的情况下主备延迟过高,这种情况下主库挂掉了切换了,会不会导致我主备数据不一致吗
    如果使用可用性优先的情况下主备延迟过高,这种情况下主库挂掉了切换了,会不会导致我主备数据不一致吗
  • [技术干货] MySQL计算天数差
    1、TO_DAYS函数   select to_days('2023-07-20') - to_days('2022-07-19') from test; // 结果366天 2、TIMESTAMPDIFF函数  select timestampdiff(param,datetime1,datetime2) from test;  计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数,param可以为FRAC_SECOND (microseconds), SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR,结果是datetime1 和datetime2之间的整数差  select timestampdiff(hour,'2022-07-10 10:20:20','2022-07-10 20:20:20')  from test; // 结果10小时 3、DATEDIFF函数 select datediff(‘2022-07-20’,'2020-06-20') from test; ———————————————— 原文链接:https://blog.csdn.net/qq_42772400/article/details/125885868 
  • [其他] Redis和MySQL如何保持数据一致性?
    在高并发的场景下,大量的请求直接访问MySQL很容易造成性能问题。所以,我们都会用Redis来做数据的缓存,削减对数据库的请求。但是,MySQL和Redis是两种不同的数据库,如何保证不同数据库之间数据的一致性就非常关键了。数据不一致的原因导致数据不一致的原因1、在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节。2、所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库。3、读取缓存步骤一般没有什么问题,但是一旦涉及到数据更新:数据库和缓存更新,就容易出现缓存(Redis)和数据库(MySQL)间的数据一致性问题。4、这个业务场景,主要是解决读数据从Redis缓存,一般都是按照下图的流程来进行业务操作。缓存先后删除问题不管是先写MySQL数据库,再删除Redis缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况。先删除缓存1、如果先删除Redis缓存数据,然而还没有来得及写入MySQL,另一个线程就来读取2、这个时候发现缓存为空,则去Mysql数据库中读取旧数据写入缓存,此时缓存中为脏数据。3、然后数据库更新后发现Redis和Mysql出现了数据不一致的问题后删除缓存1、如果先写了库,然后再删除缓存,不幸的写库的线程挂了,导致了缓存没有删除2、这个时候就会直接读取旧缓存,最终也导致了数据不一致情况3、因为写和读是并发的,没法保证顺序,就会出现缓存和数据库的数据不一致的问题解决方案延时双删策略基本思路在写库前后都进行redis.del(key)操作,并且设定合理的超时时间。伪代码如下:public void write( String key, Object data ){ redis.delKey( key ); db.updateData( data ); Thread.sleep( 500 ); redis.delKey( key );}br具体步骤1、先删除缓存2、再写数据库3、休眠500毫秒4、再次删除缓存问题:这个500毫秒怎么确定的,具体该休眠多久时间呢?1、需要评估自己的项目的读数据业务逻辑的耗时。2、这么做的目的,就是确保读请求结束,写请求可以删除读请求造成的缓存脏数据。3、当然这种策略还要考虑redis和数据库主从同步的耗时。4、最后的的写数据的休眠时间:则在读数据业务逻辑的耗时基础上,加几百ms即可。比如:休眠1秒。设置缓存过期时间是关键点1、从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案2、所有的写操作以数据库为准,只要到达缓存过期时间,缓存删除3、如果后面还有读请求的话,就会从数据库中读取新值然后回填缓存方案缺点结合双删策略+缓存超时设置,这样最差的情况就是:1、在缓存过期时间内发生数据存在不一致2、同时又增加了写请求的耗时。异步更新缓存(基于Mysql binlog的同步机制)整体思路1、涉及到更新的数据操作,利用Mysql binlog 进行增量订阅消费2、将消息发送到消息队列3、通过消息队列消费将增量数据更新到Redis上4、.操作情况读取Redis缓存:热数据都在Redis上写Mysql:增删改都是在Mysql进行操作更新Redis数据:Mysql的数据操作都记录到binlog,通过消息队列及时更新到Redis上Redis更新过程数据操作主要分为两种:1、一种是全量(将所有数据一次性写入Redis)2、一种是增量(实时更新)这里说的是增量,指的是mysql的update、insert、delate变更数据。读取binlog后分析 ,利用消息队列,推送更新各台的redis缓存数据。1、这样一旦MySQL中产生了新的写入、更新、删除等操作,就可以把binlog相关的消息推送至Redis2、Redis再根据binlog中的记录,对Redis进行更新3、其实这种机制,很类似MySQL的主从备份机制,因为MySQL的主备也是通过binlog来实现的数据一致性这里的消息推送工具你也可以采用别的第三方:kafka、rabbitMQ等来实现推送更新Redis!总结在高并发应用场景下,如果是对数据一致性要求高的情况下,要定位好导致数据和缓存不一致的原因。解决高并发场景下数据一致性的方案有两种,分别是延时双删策略和异步更新缓存两种方案。另外,设置缓存的过期时间是保证数据保持一致性的关键操作,需要结合业务进行合理的设置。引用自:https://mp.weixin.qq.com/s/Mgd8y7t--fHin4x9AZR2jQ
  • [其他] MySQL 聚簇索引
    1. 什么是聚簇索引数据库的索引从不同的角度可以划分成不同的类型,聚簇索引便是其中一种。聚簇索引英文是 Clustered Index,有时候小伙伴们可能也会看到有人将之称为聚集索引等,与之相对的是非聚簇索引或者二级索引。聚簇索引并不是一种单独的索引类型,而是一种数据的存储方式。在 MySQL 的 InnoDB 存储引擎中,所谓的聚簇索引实际上就是在同一个 B+Tree 中保存了索引和数据行:此时,数据放在叶子结点中,聚簇聚簇,意思就是说数据行和对应的键值紧凑的存在一起。2. 聚簇索引和主键有的小伙伴搞不清楚这两者之间的关系,甚至将两者划等号,这是一个巨大的误区。在有的数据库中,支持开发者自由的选择使用哪一个索引作为聚簇索引,但是 MySQL 中是不支持这个特性的。在 MySQL 中,如果表本身就有设置主键,那么主键就是聚簇索引;如果表本身没有设置主键,则会选择表中的一个唯一且非空的索引来作为聚簇索引;如果表中连唯一非空的索引都没有,那么就会自动选择表中的隐式主键来作为聚簇索引。根据上面的介绍,我们可以总结出 MySQL 中聚簇索引和主键索引的关系如下:聚簇索引不一定是主键索引。主键索引一定是聚簇索引。3. 聚簇索引优缺点优点:相互关联的数据我们可以将之保存在一起。例如有一个用户订单表,我们可以根据 用户 ID + 订单 ID 来聚集所有数据,用户 ID 可能会重复,订单 ID 则不会重复,这样我们就能够将一个用户相关的订单数据都保存在一起,如果需要查询一个用户的所有订单,就会非常快,只需要少量的磁盘 IO 就可以做到。 不需要回表,因此数据访问速度更快。在聚簇索引中,索引和数据都在同一棵 B+Tree 上,因此从聚簇索引中获取到的数据比从非聚簇索引上获取数据更快(非聚簇索引需要回表)。 对于第一点的案例,如果我们想根据用户 ID 查询到这个用户所有的订单 ID,那么此时都不用去到叶子结点了,因为支节点上就有我们需要的数据,所以直接利用覆盖索引的特性,就可以读取到需要的数据。 这些就是聚簇索引一些常见的优点,我们在日常的表设计中,其实应该充分利用好这些优点。缺点:小伙伴们发现,前面我们说的聚簇索引的优势主要是聚簇索引减少了 IO 次数,从而提高了数据库的性能,但是有的 IO 密集型应用,可能直接上一个足够大的内存,把数据都读取到内存中操作,此时聚簇索引就没有啥优势了。 随机主键会导致页分裂问题,主键顺序插入的话,相对来说效率会高一些,因为在 B+Tree 中只需要不断往后面追加即可;但是主键如果是非顺序插入的话,效率就会低很多,因为可能会涉及到页分裂问题。以上面那张图为例,假设每个节点可以保存三条数据,现在我们要插入一个主键是 4.5 的记录,那么就需要把主键为 5 的值往后移动,进而导致主键为 8 的节点也要往后移动。页分裂会导致数据插入效率降低并且占用更多的存储空间。 非聚簇索引(二级索引)查询的时候需要回表。因为一个索引就是一棵索引树,数据都在聚簇索引上,所以如果使用非聚簇索引进行搜索,非聚簇索引的叶子上存储的是主键值,先找到主键值,然后拿着主键值再来聚簇索引上搜索,这样一共就查询了两棵索引树,这就是回表。转自:cid:link_0
  • [技术干货] MySQL函数find_in_set介绍
    场景介绍 人有时会身兼数职,需要查找出其中担任某一职务的都有哪些人,如下面position字段,不同的职务用数字表示,多个职务以逗号隔开。 先要查找出担任1职务的人员,通过以下两种方式来查询。 方式一 采用模糊查询,匹配出1职务的记录,如下SQL: select * from user where position like '%1%' 查询结果如下,仔细观察你会发现position为10的也被查出来了,但这个不符合业务要求。 方式二 采用MySQL的原生函数find_in_set(str,array)来查询,SQL如下: select * from user where find_in_set(1,position) 查询结果如下,符合要求。  函数介绍 FIND_IN_SET(str,strlist),注意其中strlist只识别英文逗号。 ———————————————— 原文链接:https://blog.csdn.net/loongshawn/article/details/78611636 
  • [技术干货] Redis与MySQL的双写一致性问题【转】
    Redis与MySQL双写一致性是指在使用缓存和数据库同时存储数据的场景下( 主要是存在高并发的情况),如何保证两者的数据一致性(内容相同或者尽可能接近)。 正常业务流程:读没什么问题,关键就在于写(更新)操作,这就会出现几个问题了,这里是先更新数据库,然后对缓存操作。但对于缓存操作,是更新缓存还是删除缓存呢?或者为什么不是先操作(删除、更新)缓存在更新数据库呢?总结一下就是到底先操作缓存再操作数据库,还是先操作数据库再操作缓存?带着这几个问题接着往下讲。首先讲一下操作缓存,包括两种:更新缓存和删除缓存,如何选择?更新缓存? 删除缓存?假设都先更新数据库(因为先操作缓存再操作数据库问题较大,后面会讲) 更新缓存先更新数据库,再更新缓存。如果两个请求同时对同一条数据进行修改,那么可能出现先后顺序颠倒,导致缓存中的数据是旧的。之后的读请求读到的都是旧数据,只有当缓存失效后,才能从数据库中得到正确的值。删除缓存先更新数据库,再删除缓存。会有这样一种情况:缓存刚好失效,请求B从数据库中查询数据,得到旧值。此时请求A更新数据库,将新值写入数据库,并删除缓存。而请求B又将旧值写入缓存中,导致脏数据从上面看出现脏数据的要求要比更新缓存的要求更多,必须满足以下几个条件:缓存失效读请求 + 写请求并发更新数据库 + 删除缓存的时间要比读数据库 + 写缓存时间短前面两个很好满足,我们再看看第三点,这个真的会出现吗?数据库在更新时一般是加锁的,读操作的速度远快于写操作的,所以第三点发生概率极低(当然也可能发生)注:这里我其实不是很理解,单纯看确实发生概率低,但如果出现网络延迟等情况呢,不也会发生吗?希望好心人解惑,我反正没理解。因此,在选择删除缓存时,还需要结合其他技术来优化性能和一致性。例如:使用消息队列来异步地删除或更新缓存,避免阻塞主线程或者丢失消息。使用延时双删来增加删除成功率和减少不一致时间窗口。即在更新数据库后立即删除一次缓存,并在一定时间间隔后再次删除一次。 对比在更新缓存中, 每次去更新缓存,但是缓存中的数据不一定会被马上读取,这就会导致缓存中可能存放了很多不常访问的数据,浪费缓存资源。而且很多情况下,写到缓存中的值,并不是与数据库中的值一一对应的,很有可能是先查询数据库,再经过一系列「计算」得出一个值,才把这个值才写到缓存中。​ 由此可见,这种更新缓存的方案,不仅缓存利用率不高,还会造成机器性能的浪费。所以我们一般考虑删除缓存先更新缓存再更新数据库在更新数据时,先将新数据写入缓存(Redis),再将新数据写入数据库(MySQL) 但其存在一下问题:缓存更新成功,但数据库更新失败,导致数据不一致 例:用户修改了自己的昵称,系统先将新的昵称写入缓存,然后再更新数据库。但是在更新数据库的过程中,发生了网络故障或者数据库宕机等异常情况,导致数据库中的昵称没有被修改。这样就会出现缓存中的昵称和数据库中的昵称不一致的情况。缓存更新成功,但数据库更新延迟,导致其他请求读取到旧的数据 例:用户下单了一个商品,系统先将订单状态写入缓存,然后再更新数据库。但是在更新数据库的过程中,由于并发量大或者其他原因,导致数据库的写入速度慢于缓存的写入速度。这样就会出现其他请求从缓存中读取到订单状态为已支付,而从数据库中读取到订单状态为未支付的情况。缓存更新成功,但在数据库更新之前有其他请求查询了缓存和数据库,并将旧的数据写回缓存,覆盖了新的数据 例:用户A修改了自己的头像,并上传到服务器上。系统先将新的头像地址写入缓存,并返回给用户A显示。然后再将新的头像地址更新到数据库中。但是在这个过程中,用户B访问了用户A的个人主页,并从缓存中读取到了新的头像地址。由于缓存失效策略或者其他原因(比如重启),导致缓存被清空或者过期。这时候用户B再次访问用户A 的个人主页,并从数据库中读取到了旧的头像地址,并将其写回缓存中。这样就会出现缓存中 的头像地址和 数据库 中 的头像地址不一致 的情况。上面说了一堆,其实总结就是缓存更新成功了,数据库没更新(更新失败),导致缓存存的是最新值,数据库存的是旧值。如果缓存失效了,就会拿到数据库中的旧值。 后面我自己也搞疑惑了,既然是因为数据库更新失败导致的问题,那我是不是只要保证数据库更新成功就可以解决数据不一致的问题,当数据库更新失败时,不停的重试更新数据库,直到数据库更新完成。后面发现自己太天真,其中存在很多问题,比如:如果数据库更新失败的原因是数据库宕机或者网络故障,那么你不停地重试更新数据库可能会造成更大的压力和延迟,甚至导致数据库恢复困难。如果数据库更新失败的原因是数据冲突或者业务逻辑错误,那么你不停地重试更新数据库可能会导致数据丢失或者数据错乱,甚至影响其他用户的数据。如果你不停地重试更新数据库,那么你需要考虑如何保证重试的幂等性和顺序性,以及如何处理重试过程中发生的异常情况。 所以,这种方法并不是一个很好的解决方案。先更新数据库,再更新缓存当有一个更新操作时,先更新数据库数据,然后再更新对应的缓存数据 但是,这种方案也有一些问题和风险,比如:如果更新数据库成功了,但是更新缓存失败了,那么就会导致缓存中就会保留旧的数据,而数据库中已经是新的数据,即脏数据。如果在更新数据库和更新缓存之间,有其他请求查询了同一个数据,并且发现缓存存在,那么就会从缓存中读取旧的数据。这样也会造成缓存和数据库之间的不一致性。 因此,在使用更新缓存操作时,无论谁先谁后,但凡后者发生异常,就会对业务造成影响。(还是上面那张图)那么如何处理异常情况来保证数据一致性呢这些问题的源头都是多线程并发所导致的,所以最简单的方法就是加锁(分布式锁)。两个线程要修改同一条数据,每个线程在改之前,先去申请分布式锁,拿到锁的线程才允许更新数据库和缓存,拿不到锁的线程,返回失败,等待下次重试。这么做的目的,就是为了只允许一个线程去操作数据和缓存,避免并发问题。​ 但加锁费时费力,肯定不推荐。并且,每次去更新缓存,但是缓存中的数据不一定会被马上读取,这就会导致缓存中可能存放了很多不常访问的数据,浪费缓存资源。而且很多情况下,写到缓存中的值,并不是与数据库中的值一一对应的,很有可能是先查询数据库,再经过一系列「计算」得出一个值,才把这个值才写到缓存中。​ 由此可见,这种更新数据库 + 更新缓存的方案,不仅缓存利用率不高,还会造成机器性能的浪费。所以此时我们需要考虑另外一种方案:删除缓存先删除缓存再更新数据库当有一个更新操作时,先删除对应的缓存数据,然后再更新数据库数据 但是,这种方案也有一些问题和风险,比如:如果删除缓存后,更新数据库失败了,那么就会导致缓存丢失,下次查询时需要重新从数据库加载数据,增加了数据库压力和响应时间。如果在删除缓存和更新数据库之间,有其他请求查询了同一个数据,并且发现缓存不存在,那么就会从数据库中读取旧的数据,并写入到缓存中。这样就会造成缓存和数据库之间的不一致性。先更新数据库,再删除缓存当有一个更新操作时,先更新数据库数据,再删除缓存上面其实讲过了,我再重复一遍吧会有这样一种情况:缓存刚好失效,请求B从数据库中查询数据,得到旧值。此时请求A更新数据库,将新值写入数据库,并删除缓存。而请求B又将旧值写入缓存中,导致脏数据从上面看出现脏数据的要求要比更新缓存的要求更多,必须满足以下几个条件:缓存失效读请求 + 写请求并发更新数据库 + 删除缓存的时间要比读数据库 + 写缓存时间短前面两个很好满足,我们再看看第三点,这个真的会出现吗?数据库在更新时一般是加锁的,读操作的速度远快于写操作的,所以第三点发生概率极低所以,解决双写问题更适合的方法是先更新数据库,再删除缓存,当然具体场景具体分析,不定说一定就是这个。讲解了这些操作后会出现的问题,那么为了避免这些问题,如何做呢?先删除缓存再更新数据库,然后使用异步线程或消息队列来重建缓存。先更新数据库再删除缓存,并设置一个合理的过期时间来保证缓存的有效性。使用分布式锁或乐观锁来控制并发访问,并保证每次只有一个请求能够操作缓存和数据库 ……下面讲几种常见的方法以保证双写一致性解决方案1. 重试上面也提到过,当第二步操作失败时,我就重试嘛,尽可能地补救,但重试的成本太大,上面讲过就不重复了。2. 异步重试​ 既然重试方法占用资源,那我就做异步。在删除或更新缓存时,如果操作失败,不立即返回错误,而是通过一些机制(如消息队列、定时任务、订阅binlog等)来触发缓存的重试操作。这样可以避免同步重试缓存时的性能损耗和阻塞问题,但也可能导致缓存和数据库的数据不一致的时间较长。2.1 使用消息队列实现重试消息队列保证可靠性:写到队列中的消息,成功消费之前不会丢失(重启项目也不担心)消息队列保证消息成功投递:下游从队列拉取消息,成功消费后才会删除消息,否则还会继续投递消息给消费者(符合我们重试的需求)使用消息队列异步重试缓存的情况是指,当信息发生变化时,先更新数据库,然后删缓存,如果删除成功就皆大欢喜,如果删除失败,则将需要删除的key发送到消息队列。另外有一个消费者线程从消息队列中获取要删除的key,并根据key删除或更新Redis中的缓存。如果操作失败,则重新发送到消息队列中进行重试。注:也可以不先尝试删除,直接发送给消息队列,让消息队列举例来说,假设有一个用户信息表,需要将用户信息缓存在Redis中。如果采用使用消息队列异步重试缓存的方案,可以有以下几个步骤:当用户信息发生变化时,先更新数据库,并返回成功结果给前端。尝试去删除缓存,成功则结束操作,失败则将要删除或更新缓存的操作生成一个消息(比如包含key和操作类型),并发送到消息队列中(比如使用Kafka或RabbitMQ)。另外有一个消费者线程从消息队列中订阅并获取这些消息,并根据消息内容删除或更新Redis中的对应信息。如果删除或更新缓存成功,则把这个消息从消息队列中移除(丢弃),以免重复操作。如果删除或更新缓存失败,则执行失败策略,比如设置一个延迟时间或者一个重试次数限制,然后重新发送这个消息到消息队列中进行重试。如果重试超过一定次数仍然失败,则向业务层发送报错信息,并记录日志。2.2 Binlog实现异步重试删除使用binlog实现一致性的基本思路是利用binlog日志来记录数据库的变更操作,然后通过主从复制或者增量备份的方式来同步或者恢复数据。举例来说,如果我们有一个主数据库和一个从数据库,我们可以在主数据库上开启binlog日志,并设置从数据库作为它的复制节点。这样,当主数据库上发生任何变更操作时,它会将对应的binlog日志发送给从数据库,从数据库则会根据binlog日志来执行相同的操作,从而保证数据一致性。另外,如果我们需要恢复某个时间点之前的数据,我们也可以利用binlog日志来实现。首先,我们需要找到对应时间点之前的最近一个全量备份文件,并将其恢复到目标数据库。然后,我们需要找到对应时间点之前的所有增量备份文件(即binlog日志文件),并按照顺序将其应用到目标数据库。这样,我们就可以恢复出目标时间点之前的数据状态了。使用 Binlog 实时更新/删除 Redis 缓存。利用 Canal,即将负责更新缓存的服务伪装成一个 MySQL 的从节点,从 MySQL 接收 Binlog,解析 Binlog 之后,得到实时的数据变更信息,然后根据变更信息去更新/删除 Redis 缓存;MQ+Canal 策略,将 Canal Server 接收到的 Binlog 数据直接投递到 MQ 进行解耦,使用 MQ 异步消费 Binlog 日志,以此进行数据同步;注:binlog日志是MySQL的二进制日志,它记录了对数据库的变更操作,比如插入、更新、删除等。 binlog日志有两个主要作用,一个是主从复制,另一个是增量备份。主从复制是指在一个主数据库和一个或多个从数据库之间实现数据的同步。主数据库会将自己的binlog日志发送给从数据库,从数据库则会根据binlog日志来执行相同的操作,从而保证数据一致性。这样可以提高数据的可用性和可靠性,也可以实现负载均衡和故障转移。增量备份是指在全量备份的基础上,定期备份数据库的变更操作。全量备份是指将整个数据库的数据完整地备份到一个文件中。增量备份则是指将每次变更操作对应的binlog日志文件备份到另一个文件中。这样可以减少备份所占用的空间和时间,也可以实现灵活地恢复数据到任意时间点。至此,我们可以得出结论,想要保证数据库和缓存一致性,推荐采用「先更新数据库,再删除缓存」方案,并配合「消息队列」或「订阅变更日志」的方式来做。3. 延时双删我们重点在将先更新数据库,在删除缓存。那如果我要先删除缓存,再更新数据库呢?回顾之前讲的先删除缓存,再更新数据库,它会出现旧值覆盖缓存的问题,那好办,我们直接把这个旧值给删了不就完了吗,延时双删就是这个原理,它的基本思路是:先删除缓存再更新数据库休眠一段时间(根据系统情况确定)再次删除缓存这样做的目的是为了防止在更新数据库后,有其他线程读取到旧的缓存数据,并将其写回缓存,导致数据不一致。举个例子:假设有一个用户信息表,其中有一个字段是用户积分。现在有两个线程A和B同时对用户积分进行操作:线程A要给用户增加100积分线程B要给用户减少50积分如果使用延时双删策略,那么线程A和B的执行过程可能如下:线程A先删除缓存中的用户信息线程A再从数据库中读取用户信息,发现用户积分为1000线程A将用户积分加上100,变为1100,并更新到数据库中线程A休眠5秒(假设这个时间足够让数据库同步)线程A再次删除缓存中的用户信息线程B先删除缓存中的用户信息线程B再从数据库中读取用户信息,发现用户积分为1100(因为线程A已经更新了)线程B将用户积分减去50,变为1050,并更新到数据库中线程B休眠5秒(假设这个时间足够让数据库同步)线程B再次删除缓存中的用户信息这样最终结果就是:数据库中的用户积分为1050,缓存中没有该用户信息。当下次有请求查询该用户信息时,就会从数据库中读取并写入到缓存中。这样就保证了数据一致性。延时双删适用于高并发场景,特别是对数据的修改操作比较频繁,而查询操作比较少的情况。这样可以减轻数据库的压力,提高性能,同时保证数据的最终一致性。延时双删也适用于数据库有主从同步延迟的场景,因为它可以避免在更新数据库后,从库还没有同步完成时,读取到旧的缓存数据,并将其写回缓存。注: 这个休眠时间 = 读业务逻辑数据的耗时 + 几百毫秒。 为了确保读请求结束,写请求可以删除读请求可能带来的缓存脏数据。总结好了,总结一下这篇文章的重点。Redis与MySQL的双写一致性问题是指在使用缓存和数据库同时存储数据的场景下,如何保证两者的数据一致性。这个问题主要涉及到以下几个方面:缓存更新策略:缓存更新策略有三种,分别是先更新缓存再更新数据库,先更新数据库再更新缓存,先删除缓存再更新数据库 和先更新数据库再删除缓存。每种策略都有可能导致数据不一致的情况。数据库主从同步延迟:如果使用了主从复制模式来提高数据库的可用性和读写分离能力,那么就可能存在主从同步延迟的问题。也就是说,在主库上执行了写操作后,并不会立即同步到从库上。这样,在读取数据时,如果从主库读取,则可能获取到最新的数据;而如果从从库读取,则可能获取到旧的数据。这样也会导致与缓存中的数据不一致。为了解决这些问题 , 可以采用以下几种方法 :采用先删除缓存,再更新数据库方案,在并发场景下依旧有不一致问题,解决方案是延迟双删,但这个延迟时间很难评估。采用先更新数据库,再删除缓存方案,为了保证两步都成功执行,需配合消息队列或订阅变更日志的方案来做,本质是通过重试的方式保证数据最终一致性。采用先更新数据库,再删除缓存方案,读写分离 + 主从库延迟也会导致缓存和数据库不一致,缓解此问题的方案是延迟双删,凭借经验发送延迟消息到队列中,延迟删除缓存,同时也要控制主从库延迟,尽可能降低不一致发生的概率。总之,根据场景选择适合自己的方案
  • [技术干货] Mysql8断电崩溃解决【转】
    一、概述单机Mysql8数据库服务器运行过程中突然断电,导致数据库崩溃,无法重启。二、查找原因查看mysql运行错误日志:WIN-SOTMI68HRV6.err (在Data目录下)InnoDB: End of page dumpInnoDB: Page may be a system page2023-02-01T09:31:02.878917Z 0 [Warning] [MY-010915] [Server] 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release.2023-02-01T09:31:02.882631Z 0 [System] [MY-010116] [Server] C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqld.exe (mysqld 8.0.23) starting as process 34962023-02-01T09:31:02.923391Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.2023-02-01T09:31:05.964384Z 1 [ERROR] [MY-011971] [InnoDB] Tablespace 'innodb_system' Page [page id: space=0, page number=5] log sequence number 3275776865 is in the future! Current system log sequence number 3197057036.2023-02-01T09:31:05.966225Z 1 [ERROR] [MY-011972] [InnoDB] Your database may be corrupt or you may have copied the InnoDB tablespace but not the InnoDB log files. Please refer to http://dev.mysql.com/doc/refman/8.0/en/forcing-innodb-recovery.html for information about forcing recovery.2023-02-01T09:31:05.98InnoDB: End of page dumpInnoDB: Page may be a system page2023-02-01T11:03:39.767939Z 1 [ERROR] [MY-011906] [InnoDB] Database page corruption on disk or a failed file read of page [page id: space=4294967278, page number=101]. You may have to recover from a backup. len 16384; hex 4359822100000065000000000000000000000000c340647700060000000000000000ffffffeefffffffe0000000000000000ffffffff0000ffffffff0000ffffffee000000580932000000d600000154fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff很明显[ERROR] ,找不到磁盘文件。通过上述日志可以得知:数据库出现错误,无法重启。原因:为了保护数据,InnoDB使用校验和(与页储存在一起)。当InnoDB从磁盘读取时,它计算每个页的校验和,并与磁盘加载的校验和进行比较。如果值是不同的,可能真的发生了一些错误。InnoDB将关闭MySQL服务器,以防止进一步的逻辑或物理损坏。三、解决方案1.如何找出损坏发生的原因没有通用的解决方案。最典型的是有一些硬件问题,例如:物理磁盘或内存故障,坏的驱动器/控制器,甚至操作系统内核的bug。下面是一些建议:在Linux平台上,有时会重置页缓存能解决这个问题:1echo 2 > /proc/sys/vm/drop_caches检查系统日志有没有可能的硬件故障。如果InnoDB每次在特定页崩溃,最典型的是物理磁盘发生故障:运行对于你的OS /硬件的详细磁盘诊断。如果崩溃是随机的且不在相同查询重复,可能是RAM故障:运行详细的RAM诊断。在MySQL关闭时,用innochecksum工具检查InnoDB文件是有帮助的。作者这里故障原因是断电导致数据出现问题,只能重装Mysql。2.如何从损坏中恢复最重要的是执行详细的硬件诊断,以消除问题扩散的机会。如果操作系统I / O缓存是磁盘读损坏的原因,重置缓存或重新启动操作系统应有助于消除当前的问题,数据库可能会重新运作。有时唯一的解决办法是在有效恢复模式下备份数据。笔者后面尝试强制启动,可以启动Mysql,但是数据库只能读不能写,通过日志又找不到损坏的数据表,无奈,只能先备份数据库,然后重装Mysql。修改数据库,一直报错:running in read_only mode 1836将mysql改为强制启动:在my.ini中【mysqld】节点下加上1innodb_force_recovery=0然后对数据库进行备份。备份方式:一、数据库备份第一种:(cmd窗口使用)在命令提示符用mysqldump命令行备份数据库。命令格式mysqldump -u用户名 -p 数据库名 > 保存名.sql范例:1mysqldump -uroot -p dataname > d:\data.sql(导出数据库dataname到data.sql文件)提示输入密码时,输入该数据库用户名的密码。第二种:指定导出备份编码1mysqldump -u root -p密码 --default-character-set=数据编码 数据库名称> data.sql案例:1mysqldump -u root -p123456 --default-character-set=utf8 discuss_chi>d:/data.sqlmySQL数据库在windows环境下备份与恢复:二,恢复数据库,一共二种方式。第一种;定义还原编码类型(cmd窗使用)定义编码导入:1mysql -u root -p --default-character-set=utf8 -f dataname<d:/dis.sql如果乱码使用二进导入1mysql -u root -p --default-character-set=binary -f dataname<d:/dis.sql第二种:source 命令(mysql控制台窗口使用)进入mysql数据库控制台,如在运行中输入:mysql -u root -p1mysql>use databasename;1、确定数据库默认编码,比如编码为gbk,将读入途径编码同样设为gbk,命令为:set names gbk;(导入数据出现乱码的时候用平常不用)2、然后使用source命令,后面参数为脚本文件(如这里用到的.sql)1mysql>source d:\data.sql;备份后,重装Mysql,恢复数据库。
  • [技术干货] mysql去重查询的三种方法小结【转】
    数据库生成环境中经常会遇到表中有重复的数据,或者进行关联过程中产生重复数据,下面介绍三种剔除重复数据的方法,请针对自己的应用场景选择使用。一、插入测试数据下图测试数据中user_name为lilei、zhaofeng的用户是重复数据。二、剔除重复数据方法1.方法一:使用distinct代码如下(示例):1select distinct user_name,email,address from t_user;如下图,已将数据剔重,重复数据仅保留1条。2.方法二:使用group by123SELECT user_name,email,address     FROM t_user     GROUP BY user_name, email, address;如下图,已将数据剔重,重复数据仅保留1条。3.方法三:使用开窗函数(1)如果你的数据库是MySQL8以上版本你可以直接使用开窗函数row_number()12345678SELECT *FROM(    SELECT t.*,            ROW_NUMBER() OVER(PARTITION BY user_name           ORDER BY last_login DESC) rn    FROM table AS t    ) AS t_userWHERE rn = 1;(2)如果你的数据库版本低于MySQL8,使用类row_number()方法123456789101112select user_name, email, address from (    select        b.*,        @rownum := @rownum+1 ,-- 定义用户变量@rownum来记录数据的行号        if(@pdept=b.user_name,@rank:=@rank+1,@rank:=1) as rank,-- 如果当前分组user_name和上一次分组user_name相同,则@rank(对每一组的数据进行编号)值加1,否则表示为新的分组,从1开始        @pdept:=b.user_name -- 定义变量@pdept用来保存上一次的分组id    from (select * from t_user) b ,        (select @rownum :=0 , @pdept := null ,@rank:=0) c  -- 初始化自定义变量值    order by b.user_name,b.last_login desc -- 该排序必须,否则结果会不对) resultwhere rank = 1;如下图,已将数据剔重,重复数据仅保留1条。
  • [其他] 企业MySQL开发规范
    ​命名规范一. 数据库对象全局命名规范命名使用具有意义的英文词汇,词汇中间以下划线_分隔。命名只能使用英文字母. 数字. 下划线,以英文字母开头。避免用MySQL的保留字,如:backup. call. group等。所有数据库对象使用小写字母。二. 数据库命名规范数据库命名尽量不超过30个字符。数据库命名一般为项目名称+代表库含义的简写,比如IM项目的工作流数据库,可以是 im_flow。数据库创建时必须添加默认字符集和校对规则子句。默认字符集为UTF8(已迁移dumbo的使用utf8mb4)。命名应使用小写。三. 表命名规范常规表表名以t_开头,t代表table的意思,命名规则即 t + 模块(包含模块含义的简写)+ 表(包含表含义的简写),比如用户模块的教育信息表:t_user_eduinfo。临时表(RD. QA或DBA同学用于数据临时处理的表),命名规则:temp前缀+模块+表+日期后缀:temp_user_eduinfo_20210719。备份表(用于保存和归档历史数据或者作为灾备恢复的数据)命名规则,bak前缀+模块+表+日期后缀:bak_user_eduinfo_20210719。同一个模块的表尽可能使用相同的前缀,表名称尽可能表达含义。多个单词以下划线 _ 分隔。常规表表名尽量不超过30个字符,temp表和bak表视情况而定,也尽量简短为宜,命名应使用小写。四. 字段命名规范字段命名需要表示其实际含义的英文单词或简写,单词之间用下划线 _ 进行连接,如 service_ip. service_port。各表之间相同意义的字段必须同名,比如a表和b表都有创建时间,应该统一为create_time,不一致会很混乱。多个单词以下划线 _ 分隔。字段名尽量不超过30个字符,命名应该使用小写。数据库对象设计规范一. 存储引擎的选择如无特殊需求,必须使用innodb存储引擎。可以通过 show variables like 'default_storage_engine' 来查看当前默认引擎。主要有MyISAM 和 InnoDB,从5.5版本开始默认使用 InnoDB 引擎。基本的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行速度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持以及外部键等高级数据库功能。二. 字符集的选择如无特殊要求,必须使用utf8或utf8mb4。在国内,选择对中文和各语言支持都非常完善的utf8格式是最好的方式,MySQL在5.5之后增加utf8mb4编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。所以utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换。当然,为了节省空间,一般情况下使用utf8也就够了。可以使用如下脚本来查看数据库的编码格式三. 表设计规范不同应用间所对应的数据库表之间的关联应尽可能减少,不允许使用外键对表之间进行关联,确保组件对应的表之间的独立性,为系统或表结构的重构提供可能性。目前业内的做法一般 由程序控制参照完整性。表设计的角度不应该针对整个系统进行数据库设计,而应该根据系统架构中组件划分,针对每个组件所处理的业务进行数据库设计。表必须要有PK,主键的优势是唯一标识. 有效引用. 高效检索,所以一般情况下尽量有主键字段。一个字段只表示一个含义。表不应该有重复列。禁止使用复杂数据类型(数组,自定义等),Json类型的使用视情况而定。需要join的字段(连接键),数据类型必须保持绝对一致,避免隐式转换。比如关联的字段都是int类型。设计应至少满足第三范式,尽量减少数据冗余。 一些特殊场景允许反范式化设计,但在项目评审时需要对冗余字段的设计给出解释。TEXT字段作为大体量文本存储,必须放在独立的表中 , 用PK与主表关联。如无特殊需要,禁止使用TEXT. BLOB字段。需要定期删除(或者转移)过期数据的表,通过分表解决,我们的做法是按照2/8法则将操作频率较低的历史数据迁移到历史表中,按照时间或者则曾Id做切割点。单表字段数不要太多,建议最多不要大于50个。过度的宽表对性能也是很大的影响。MySQL在处理大表时,性能就开始明显降低,所以建议单表物理大小限制在16GB,表中数据行数控制在2000W内。业内的规则是超过2000W性能开始明显降低。但是这个值是灵活的,你可以根据实际情况进行测试来判断,比如阿里的标准就是500W,百度的确是2000W。实际上是否宽表,单行数据所占用的空间都有起到作用的。如果数据量或数据增长在前期规划时就较大,那么在设计评审时就应加入分表策略,后续会有专门的文章来分析数据拆分的做法:垂直拆分(垂直分库和垂直分表). 水平拆分(分库分表和库内分表);无特殊需求,严禁使用分区表四. 字段设计规范INT:如无特殊需要,存放整型数字使用UNSIGNED INT型,整型字段后的数字代表显示长度。比如 id int(11) NOT NULLDATETIME:所有需要精确到时间(时分秒)的字段均使用DATETIME,不要使用TIMESTAMP类型。对于TIMESTAMP,它把写入的时间从当前时区转化为UTC(世界标准时间)进行存储。查询时,将其又转化为客户端当前时区进行返回。而对于DATETIME,不做任何改变,基本上是原样输入和输出。另外DATETIME存储的范围也比较大: timestamp所能存储的时间范围为:'1970-01-01 00:00:01.000000' 到 '2038-01-19 03:14:07.999999'。 datetime所能存储的时间范围为:'1000-01-01 00:00:00.000000' 到 '9999-12-31 23:59:59.999999'。 但是特殊情况,对于跨时区的业务,TIMESTAMP更为合适。VARCHAR:所有动态长度字符串 全部使用VARCHAR类型,类似于状态等有限类别的字段,也使用可以比较明显表示出实际意义的字符串,而不应该使用INT之类的数字来代替;VARCHAR(N), N表示的是字符数而不是字节数。比如VARCHAR(255),可以最大可存储255个字符(字符包括英文字母,汉字,特殊字符等)。但N应尽可能小,因为MySQL一个表中所有的VARCHAR字段最大长度是65535个字节,且存储字符个数由所选字符集决定。 如UTF8存储一个字符最大要3个字节,那么varchar在存放占用3个字节长度的字符时不应超过21845个字符。同时,在进行排序和创建临时表一类的内存操作时,会使用N的长度申请内存。(如无特殊需要,原则上单个varchar型字段不允许超过255个字符)TEXT:仅仅当字符数量可能超过20000个的时候,才可以使用TEXT类型来存放字符类数据,因为所有MySQL数据库都会使用UTF8字符集。 所有使用TEXT类型的字段必须和原表进行分拆,与原表主键单独组成另外一个表进行存放,与大文本字段的隔离,目的是。如无特殊需要,不使用MEDIUMTEXT. TEXT. LONGTEXT类型对于精确浮点型数据存储,需要使用DECIMAL,严禁使用FLOAT和DOUBLE。如无特殊需要,尽量不使用BLOB类型。如无特殊需要,字段建议使用NOT NULL属性,可用默认值代替NULL。自增字段类型必须是整型且必须为UNSIGNED,推荐类型为INT或BIGINT,并且自增字段必须是主键或者主键的一部分。五. 索引设计规范索引区分度 索引必须创建在索引选择性(区分度)较高的列上,选择性的计算方式为:  selecttivity = count(distinct c_name)/count(*); 如果区分度结果小于0.2,则不建议在此列上创建索引,否则大概率会拖慢SQL执行遵循最左前缀 对于确定需要组成组合索引的多个字段,设计时建议将选择性高的字段靠前放。使用时,组合索引的首字段,必须在where条件中,且需要按照最左前缀规则去匹配。禁止使用外键,可以在程序级别来约束完整性Text类型字段如果需要创建索引,必须使用前缀索引单张表的索引数量理论上应控制在5个以内。经常有大批量插入. 更新操作表,应尽量少建索引,索引建立的原则理论上是多读少写的场景。ORDER BY,GROUP BY,DISTINCT的字段需要添加在索引的后面,形成覆盖索引。正确理解和计算索引字段的区分度,文中有计算规则,区分度高的索引,可以快速得定位数据,区分度太低,无法有效的利用索引,可能需要扫描大量数据页,和不使用索引没什么差别。正确理解和计算前缀索引的字段长度,文中有判断规则,合适的长度要保证高的区分度和最恰当的索引存储容量,只有达到最佳状态,才是保证高效率的索引。联合索引注意最左匹配原则:必须按照从左到右的顺序匹配,MySQL会一直向右匹配索引直到遇到范围查询(>. <. between. like)然后停止匹配。 如:depno=1 and empname>'' and job=1 如果建立(depno,empname,job)顺序的索引,job是用不到索引的。应需而取策略,查询记录的时候,不要一上来就使用*,只取需要的数据,可能的话尽量只利用索引覆盖,可以减少回表操作,提升效率。正确判断是否使用联合索引(上面联合索引的使用那一小节有说明判断规则),也可以进一步分析到索引下推(IPC),减少回表操作,提升效率。避免索引失效的原则:禁止对索引字段使用函数. 运算符操作,会使索引失效。这是实际上就是需要保证索引所对应字段的”干净度“。避免非必要的类型转换,字符串字段使用数值进行比较的时候会导致索引无效。模糊查询'%value%'会使索引无效,变为全表扫描,因为无法判断扫描的区间,但是'value%'是可以有效利用索引。索引覆盖排序字段,这样可以减少排序步骤,提升查询效率尽量的扩展索引,非必要不新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。 举例子:比如一个品牌表,建立的的索引如下,一个主键索引,一个唯一索引。 PRIMARY KEY (id), UNIQUE KEY uni_brand_define (app_id,define_id) 当你同事业务代码中的检索语句如下的时候,应该立即警告了,即没有覆盖索引,也没按照最左前缀原则:select brand_id,brand_name  from  ds_brand_system  where status=?     and define_id=?     and app_id=? 建议改成如下: select brand_id,brand_name  from  ds_brand_system  where app_id=?    and define_id=?     and  status=? 六. 约束设计规范PK应该是有序并且无意义的,由开发人员自定义,尽可能简短,并且是自增序列。表中除PK以外,还存在唯一性约束的,可以在数据库中创建以“uk_”作为前缀的唯一约束索引。PK字段不允许更新。禁止创建外键约束,外键约束由程序控制。如无特殊需要,所有字段必须添加非空约束,即not null。如无特殊需要,所有字段必须有默认值。SQL使用规范一. select 检索的规范性尽量避免使用select *,join语句使用select *可能导致只需要访问索引即可完成的查询需要回表取数。 一种是可能取出很多不需要的数据,对于宽表来说,这是灾难;一种是尽可能避免回表,因为取一些根本不需要的数据而回表导致性能低下,是很不合算。严禁使用 select * from t_name,而不加任何where条件,道理一样,这样会变成全表全字段扫描。MySQL中的text类型字段存储: (1)不与其他普通字段存放在一起,因为读取效率低,也会影响其他轻量字段存取效率。 (2)如果不需要text类型字段,又使用了select *,会让该执行消耗大量io,效率也很低下在取出字段上可以使用相关函数,但应尽可能避免出现 now() , rand() , sysdate() 等不确定结果的函数,在Where条件中的过滤条件字段上严禁使用任何函数,包括数据类型转换函数。大量的计算和转换会造成效率低下,这个在索引那边也描述过了。分页查询语句全部都需要带有排序条件,否则很容易引起乱序用in()/union替换or,效率会好一些,并注意in的个数小于300严禁使用%前缀进行模糊前缀查询:如:select a,b,c from t_name where a like ‘%name’; 可以使用%模糊后缀查询如:select a,b from t_name where a like ‘name%’;避免使用子查询,可以把子查询优化为join操作 通常子查询在in子句中,且子查询中为简单SQL(不包含union. group by. order by. limit从句)时,才可以把子查询转化为关联查询进行优化。 子查询性能差的原因: (1)子查询的结果集无法使用索引,通常子查询的结果集会被存储到临时表中,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能 会受到一定的影响; (2)特别是对于返回结果集比较大的子查询,其对查询性能的影响也就越大; (3)由于子查询会产生大量的临时表也没有索引,所以会消耗过多的CPU和IO资源,产生大量的慢查询。二. 操作的规范性禁止使用不含字段列表的INSERT语句 如:insert into values ('a','b','c');  应使用  insert into t_name(c1,c2,c3) values ('a','b','c'); 。大批量写操作(UPDATE. DELETE. INSERT),需要分批多次进行操作 (1)大批量操作可能会造成严重的主从延迟,特别是主从模式下,大批量操作可能会造成严重的主从延迟,因为需要slave从master的binlog中读取日志来进行数据同步。 (2)binlog日志为row格式时会产生大量的日志。参考:cid:link_0​
  • [技术干货] centos7配置yum源安装mysql简单教程
    centos7配置yum源安装mysql简单教程CentOS 7是CentOS项目发布的开源类服务器操作系统,于2014年7月7日正式发布。 [1] CentOS 7是一个企业级的Linux发行版本,它源于RedHat免费公开的源代码进行再发行。 [2] CentOS 7内核更新至3.10.0、支持Linux容器、支持Open VMware Tools及3D图像即装即用、支持OpenJDK-7作为缺省JDK、支持内核空间内的iSCSI及FCoE、支持PTPv2等功能。下面讲讲关于centos7配置yum源安装mysql简单教程,文字的奥妙在于贴近主题相关。所以,闲话就不谈了,我们直接看下文吧,相信看完centos7配置yum源安装mysql简单教程这篇文章你一定会有所受益。一、配置yum源安装mysql(默认安装5.7版本)[root@localhost ~]#wget https://repo.mysql.com//mysql57-community-release-el7-9.noarch.rpm[root@localhost ~]#mysql57-community-release-el7-9.noarch.rpm    注:可到/etc/yum.repo.d/下修改mysql-community.repo源选择mysql的版本(如安装5.6版        本,将5.7源的enabled=1改成enabled=0。然后再将5.6源的enabled=0改成enabled=1即可)二、安装mysql    yum -y installmysql-community-server三、启动mysql服务[root@localhost ~]#Systemctlstart mysqld         #启动[root@localhost ~]#systemctlstatus mysqld        #查看运行状态● mysqld.service - MySQL Server   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)   Active: active (running) since Fri 2017-04-21 11:58:11 CST; 39min ago四、重置root密码注:mysql安装成功后在mysql 日志文件中生成了一个默认root密码,查找命令:[root@localhost ~]#cat /var/log/mysqld.log | grep temporary   2017-04-21T03:58:07.638266Z 1 [Note] A temporary password is generated for    root@localhost: :fwi#eQ#j8Kj复制字符串密码登录mysql [root@localhost ~]#mysql -uroot -p:fwi#eQ#j8Kj (-p后面的字符串就是默认生成的密码) mysql>set password=password('新密码');可能会报错!ERROR 1819 (HY000): Your passworddoes not satisfy the current policy requirements原因:刚开始设置密码必须符合密码复杂策略,mysql5.7默认安装了密码安全检查插件(validate_password),默认密码检查策略要求密码必须包含:大小写字母、数字和特殊符号,并且长度不能少于8位。分别输入这两条命令即可解决:mysql>set global validate_password_policy=0;  mysql>set global validate_password_length=4; 继续执行 mysql> set password=password('123456'); Query OK, 0 rows affected, 1 warning (0.09 sec) mysql>flush privileges;密码修改成功!退出后生效!对于以上centos7配置yum源安装mysql简单教程相关内容,大家还有什么不明白的地方吗?或者想要了解更多相关,可以继续关注我们的行业资讯板块。原文链接:https://www.yisu.com/zixun/34602.html
  • [技术干货] MySQL如何实现数据备份与恢复
    下面讲讲关于yum源安装MySQL及配置集群的详细教程,文字的奥妙在于贴近主题相关。所以,闲话就不谈了,我们直接看下文吧,相信看完yum源安装MySQL及配置集群的详细教程这篇文章你一定会有所受益。在CentOS7中默认安装有MariaDB,这个是MySQL的分支,但为了需要,还是要在系统中安装MySQL,而且安装完成之后可以直接覆盖掉MariaDB。1 下载并安装MySQL官方的 Yum Repositorywget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm使用上面的命令就直接下载了安装用的Yum Repository,大概25KB的样子,然后就可以直接yum安装了。yum -y install mysql57-community-release-el7-10.noarch.rpm之后就开始安装MySQL云服务器。yum -y install mysql-community-server这步可能会花些时间,安装完成后就会覆盖掉之前的mariadb。至此MySQL就安装完成了,然后是对MySQL的一些设置。2 MySQL数据库设置首先启动MySQLsystemctl start mysqld.service查看MySQL运行状态,运行状态如图:此时MySQL已经开始正常运行,不过要想进入MySQL还得先找出此时root用户的密码,通过如下命令可以在日志文件中找出密码:如下命令进入数据库:mysql -uroot –p输入初始密码,此时不能做任何事情,因为MySQL默认必须修改密码之后才能操作数据库:ALTER USER 'root'@'localhost' IDENTIFIED BY 'new password';这里有个问题,新密码设置的时候如果设置的过于简单会报错:首先需要设置密码的验证强度等级,设置 validate_password_policy 的全局参数为 LOW 即可,输入设值语句 “ set global validate_password_policy=LOW; ” 进行设值当前密码长度为 8 ,如果不介意的话就不用修改了,按照通用的来讲,设置为 6 位的密码,设置 validate_password_length 的全局参数为 6 即可,输入设值语句 “ set global validate_password_length=6; ” 进行设值现在可以为 mysql 设置简单密码了,只要满足六位的长度即可,ALTER USER 'root'@'localhost' IDENTIFIED BY 'a@123456';注:在默认密码的长度最小值为 4 ,由 大/小写字母各一个 + 阿拉伯数字一个 + 特殊字符一个,只要设置密码的长度小于 3 ,都将自动设值为 4设置远程主机登录(我用的是Navicat)注意:如果是生产环境不介意开启root远程登陆(安全问题)但此时还有一个问题,就是因为安装了Yum Repository,以后每次yum操作都会自动更新,需要把这个卸载掉:yum -y remove mysql57-community-release-el7-10.noarch到此数据库安装完成了。原文链接:cid:link_1zixun/7980.html
总条数:1406 到第
上滑加载中