《面试题》3、数据库MySQL

【数仓面试】数据仓库专家面试题(上) 数据仓库专家面试题,涵盖初级、中级和高级水平问题,并附上详细答案。面试题将围绕工作职责(数据仓库需求对接、ETL 实施、性能优化、数据治理等 、数据仓库架构、3NF 多维模型、大数据生态、MySQL/NoSQL 等)展开。 阅读详情

3.1 MySQL

3.1.1 基础

1.说一下 MySQL 执行一条查询语句的内部执行过程?

MySQL 执行一条查询的流程如下:
- 客户端先通过连接器连接到 MySQL 服务器;
- 连接器权限验证通过之后,先查询是否有查询缓存,如果有缓存(之前执行过此语句)则直接返回缓存数据,如果没有缓存则进入分析器;
- 分析器会对查询语句进行语法分析和词法分析,判断 SQL 语法是否正确,如果查询语法错误会直接返回给客户端错误信息,如果语法正确则进入优化器;
- 优化器是对查询语句进行优化处理,例如一个表里面有多个索引,优化器会判别哪个索引性能更好;
- 优化器执行完就进入执行器,执行器则开始执行语句进行查询比对了,直到查询到满足条件的所有数据,然后进行返回。

2、常用的存储引擎 InnoDB 和 MyISAM 有什么区别?

InnoDB 和 MyISAM 最大的区别是 InnoDB 支持事务,而 MyISAM 不支持事务,它们其他主要区别如下:

- InnoDB 支持崩溃后安全恢复,MyISAM 不支持崩溃后安全恢复;
- InnoDB 支持行级锁,MyISAM 不支持行级锁,只支持到表锁;
- InnoDB 支持外键,MyISAM 不支持外键;
- MyISAM 性能比 InnoDB 高;
- MyISAM 支持 FULLTEXT 类型的全文索引,InnoDB 不支持 FULLTEXT 类型的全文索引,但是 InnoDB 可以使用 sphinx 插件支持全文索引,并且效果更好;
- InnoDB 主键查询性能高于 MyISAM;
- count(*) MyISAM内置计数器,只要简单的读出保存好的行数,而InnoDB需要遍历全表计算;

3、什么是独立表空间和共享表空间?它们的区别是什么?

- 共享表空间: 数据库的所有表数据,索引文件全部放在一个文件中,默认这个共享表空间的文件路径在 data 目录下。

- 独立表空间:每一个表都将会生成以独立的文件方式来进行存储。

- 区别: 如果把表放再共享表空间,即使表删除了空间也不会删除,因此表依然很大,而独立表空间如果删除表就会清除空间。

4、MySQL 是如何处理死锁?

- 通过 innodb_lock_wait_timeout 来设置超时时间,一直等待直到超时;
- 发起死锁检测,发现死锁之后,主动回滚死锁中的某一个事务,让其他事务继续执行。

5、什么是全局锁?它的应用场景有哪些?使用会导致什么问题?

- 概念:全局锁就是对整个数据库实例加锁;
- 应用场景:做全量逻辑备份,这个时候整个库会处于完全的只读状态。
- 问题:使用全局锁会使整个系统不能执行更新操作,所有的更新业务会出于等待状态;如果你是在从库进行备份,则会导致主从同步严重延迟。

6、MySQL 性能指标都有哪些?如何得到这些指标?

- QPS(Queries Per Second),每秒查询数,一台数据库每秒能够处理的查询次数;
- TPS(Transactions Per Second),每秒处理事务数。

这些性能指标可以通过 show status 来查询当前数据库状态的结果信息中估算出来,show status 会有 300 多条状态信息记录,其中以下这些信息 QPS 和 TPS 有关系:

- Uptime,服务器已经运行的时间,单位秒;
- Questions,已经发送给数据库查询数;
- Com_select,查询次数,实际查询次数;
- Com_insert,插入次数;
- Com_delete,删除次数;
- Com_update,更新次数;
- Com_commit,事务次数;
- Com_rollback,回滚次数。

7、MySQL 中的重要日志分为哪几个?

① 错误日志:用来记录 MySQL 服务器运行过程中的错误信息,比如,无法加载 MySQL 数据库的数据文件,或权限不正确等都会被记录在此,还有复制环境下,从服务器进程的信息也会被记录进错误日志。默认情况下,错误日志是开启的,且无法被禁止。默认情况下,错误日志是存储在数据库的数据文件目录中,名称为 hostname.err,其中 hostname 为服务器主机名。在 MySQL 5.5.7 之前,数据库管理员可以删除很长时间之前的错误日志,以节省服务器上的硬盘空间, MySQL 5.5.7 之后,服务器将关闭此项功能,只能使用重命名原来的错误日志文件,手动冲洗日志创建一个新的,命令为:
    mv hostname.err hostname.err.old
    mysqladmin flush-logs

② 查询日志:查询日志在 MySQL 中被称为 general log(通用日志),查询日志里的内容不要被“查询日志”误导,认为里面只存储 select 语句,其实不然,查询日志里面记录了数据库执行的所有命令,不管语句是否正确,都会被记录,具体原因如下:

- insert 查询为了避免数据冲突,如果此前插入过数据,则当前插入的数据如果跟主键或唯一键的数据重复那肯定会报错;
- update 时也会查询因为更新的时候很可能会更新某一块数据;
- delete 查询,只删除符合条件的数据;

因此都会产生日志,在并发操作非常多的场景下,查询信息会非常多,那么如果都记录下来会导致 IO 非常大,影响 MySQL 性能。因此如果不是在调试环境下,是不建议开启查询日志功能的。

查询日志的开启有助于帮助我们分析哪些语句执行密集,执行密集的 select 语句对应的数据是否能够被缓存,同时也可以帮助我们分析问题,因此,可以根据自己的实际情况来决定是否开启查询日志。

查询日志模式是关闭的,可以通过以下命令开启查询日志:

set global general_log=1

set global log_output='table';

general_log=1 为开启查询日志,0 为关闭查询日志,这个设置命令即时生效,不用重启 MySQL 服务器。

③ 慢日志:慢查询会导致 CPU、IOPS、内存消耗过高,当数据库遇到性能瓶颈时,大部分时间都是由于慢查询导致的。开启慢查询日志,可以让 MySQL 记录下查询超过指定时间的语句,之后运维人员通过定位分析,能够很好的优化数据库性能。默认情况下,慢查询日志是不开启的,只有手动开启了,慢查询才会被记录到慢查询日志中。使用如下命令记录当前数据库的慢查询语句:

set global slow_query_log='ON';

使用 set global slow_query_log='ON' 开启慢查询日志,只是对当前数据库有效,如果 MySQL 数据库重启后就会失效。因此如果要永久生效,就要修改配置文件 my.cnf,设置 slow_query_log=1 并重启 MySQL 服务器。

④ redo log(重做日志):为了最大程度的避免数据写入时,因为 IO 瓶颈造成的性能问题,MySQL 采用了这样一种缓存机制,先将数据写入内存中,再批量把内存中的数据统一刷回磁盘。为了避免将数据刷回磁盘过程中,因为掉电或系统故障带来的数据丢失问题,InnoDB 采用 redo log 来解决此问题。

⑤ undo log(回滚日志):用于存储日志被修改前的值,从而保证如果修改出现异常,可以使用 undo log 日志来实现回滚操作。

undo log 和 redo log 记录物理日志不一样,它是逻辑日志,可以认为当 delete 一条记录时,undo log 中会记录一条对应的 insert 记录,反之亦然,当 update 一条记录时,它记录一条对应相反的 update 记录,当执行 rollback 时,就可以从 undo log 中的逻辑记录读取到相应的内容并进行回滚。undo log 默认存放在共享表空间中,在MySQL 5.6 中,undo log 的存放位置还可以通过变量 innodb_undo_directory 来自定义存放目录,默认值为“.”表示 datadir 目录。

⑥ bin log(二进制日志):是一个二进制文件,主要记录所有数据库表结构变更,比如,CREATE、ALTER TABLE 等,以及表数据修改,比如,INSERT、UPDATE、DELETE 的所有操作,bin log 中记录了对 MySQL 数据库执行更改的所有操作,并且记录了语句发生时间、执行时长、操作数据等其他额外信息,但是它不记录 SELECT、SHOW 等那些不修改数据的 SQL 语句。 binlog 的作用如下:

- 恢复(recovery):某些数据的恢复需要二进制日志。比如,在一个数据库全备文件恢复后,用户可以通过二进制日志进行 point-in-time 的恢复;
- 复制(replication):其原理与恢复类似,通过复制和执行二进制日志使一台远程的 MySQL 数据库(一般称为 slave 或者 standby)与一台 MySQL 数据库(一般称为 master 或者 primary)进行实时同步;
- 审计(audit):用户可以通过二进制日志中的信息来进行审计,判断是否有对数据库进行注入攻击。

除了上面介绍的几个作用外,binlog 对于事务存储引擎的崩溃恢复也有非常重要的作用,在开启 binlog 的情况下,为了保证 binlog 与 redo 的一致性,MySQL 将采用事务的两阶段提交协议。当 MySQL 系统发生崩溃时,事务在存储引擎内部的状态可能为 prepared(准备状态)和 commit(提交状态)两种,对于 prepared 状态的事务,是进行提交操作还是进行回滚操作,这时需要参考 binlog,如果事务在 binlog 中存在,那么将其提交;如果不在 binlog 中存在,那么将其回滚,这样就保证了数据在主库和从库之间的一致性。

binlog 默认是关闭状态,可以在 MySQL 配置文件(my.cnf)中通过配置参数 log-bin = [base-name] 开启记录 binlog 日志,如果不指定 base-name,则默认二进制日志文件名为主机名,并以自增的数字作为后缀,比如:mysql-bin.000001,所在目录为数据库所在目录(datadir)。

通过以下命令来查询 binlog 是否开启:show variables like 'log_%';

binlog 格式分为 STATEMENT、ROW 和 MIXED 三种:
- STATEMENT 格式的 binlog 记录的是数据库上执行的原生 SQL 语句。这种格式的优点是简单,简单地记录和执行这些语句,能够让主备保持同步,在主服务器上执行的 SQL 语句,在从服务器上执行同样的语句。另一个好处是二进制日志里的时间更加紧凑,因此相对而言,基于语句的复制模式不会使用太多带宽,同时也节约磁盘空间,并且通过 mysqlbinlog 工具容易读懂其中的内容。缺点就是同一条 SQL 在主库和从库上执行的时间可能稍微或很大不相同,因此在传输的二进制日志中,除了查询语句,还包括了一些元数据信息,如当前的时间戳。即便如此,还存在着一些无法被正确复制的 SQL,比如,使用 INSERT INTO TB1 VALUE(CUURENT_DATE()) 这一条使用函数的语句插入的数据复制到当前从服务器上来就会发生变化,存储过程和触发器在使用基于语句的复制模式时也可能存在问题;另外一个问题就是基于语句的复制必须是串行化的,比如,InnoDB 的 next-key 锁等,并不是所有的存储引擎都支持基于语句的复制。
- ROW 格式是从 MySQL 5.1 开始支持基于行的复制,也就是基于数据的复制,基于行的更改。这种方式会将实际数据记录在二进制日志中,它有其自身的一些优点和缺点,最大的好处是可以正确地复制每一行数据,一些语句可以被更加有效地复制,另外就是几乎没有基于行的复制模式无法处理的场景,对于所有的 SQL 构造、触发器、存储过程等都能正确执行;它的缺点就是二进制日志可能会很大,而且不直观,因此,你不能使用 mysqlbinlog 来查看二进制日志,也无法通过看二进制日志判断当前执行到那一条 SQL 语句。现在对于 ROW 格式的二进制日志基本是标配了,主要是因为它的优势远远大于缺点,并且由于 ROW 格式记录行数据,因此可以基于这种模式做一些 DBA 工具,比如数据恢复,不同数据库之间数据同步等。
- MIXED 也是 MySQL 默认使用的二进制日志记录方式,但 MIXED 格式默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。比如用到 UUID()、USER()、CURRENT_USER()、ROW_COUNT() 等无法确定的函数。

3.1.2 索引

1、聚簇索引和非聚簇索引的区别

本质上的区别:聚簇索引是有序的,非聚簇索引是无序,聚簇索引指向主键,非聚簇索引直接指针指向数据,根本区别是表中记录的物理顺序和索引排序是否一致,是:聚簇,否:非聚簇;
1.非聚簇索引(MyISAM)
    概念:非聚簇索引的两棵 B+树看上去没什么不同, 节点的结构完全一致只是存储的内容不同而已, 
    主键索引 B+树的节点存储了主键, 辅助键索引B+树存储了辅助键。 表数据存储在独立的地方, 这两颗 B+树的叶子节点都使用一个地址指向真正的表数据, 对于表数据来说, 这两个键没有任何差别。 
    由于索引树是独立的, 通过辅助键检索无需访问主键的索引树。
    应用场景:a.此列包含大数量不同的值;
              b.频繁更新的列;
2.聚簇索引(InnoDB的主键索引) 
- 主键索引查询:将主键组织到一棵 B+树中, 而行数据就储存在叶子节点上, 若使用"where id = 1"这样的条件查找主键, 则按照 B+树的检索算法即可查找到对应的叶节点, 之后获得行数据。 
- 辅助索引查询:若辅助索引为name,对 name 列进行条件搜索,则需要两个步骤:
    1.在辅助索引 B+树中检索 Name, 到达其叶子节点获取对应的主键;
    2.使用主键在主索引 B+树种再执行一次 B+树检索操作,最终到达叶子节点即可获取整行数据。
    注意:如果查询的字段只有辅助索引的字段,此时不回表,如果查询的字段里有非辅助索引字段,则需要回表查。
- 注:为什么不建议使用过长的字段作为主键?因为所有的辅助索引都在引用主索引,过长的主索引会令辅助索引变得过大。

2、InnoDB 为什么要使用 B+ 树,而不是 B 树、Hash、红黑树或二叉树?

- B 树:不管叶子节点还是非叶子节点,都会保存数据,这样导致在非叶子节点中能保存的指针数量变少(有些资料也称为扇出),指针少的情况下要保存大量数据,只能增加树的高度,导致 IO 操作变多,查询性能变低。
- Hash:虽然可以快速定位,但是没有顺序,IO 复杂度高。
- 二叉树:树的高度不均匀,不能自平衡,查找效率跟数据有关(树的高度),并且 IO 代价高。
- 红黑树:树的高度随着数据量增加而增加,IO 代价高。
- B+树:索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。
    1.高度原因(只有三层):B+树中的每个结点可以包含大量关键字,这样树的深度降低了,所以任何关键字的查询必须走一条从根结点到叶子结点的路,所有关键字查询的路径长度相同,导致每个数据查询效率相当,减少了磁盘I/O的存取次数。
    2.磁盘预读原理和局部性原理:将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。

3、explain分析优化

注意:关联查询时,尽可能使用小表驱动大表,尽量减少临时表的大小
重要指标:
    (1) select_type(查询中每个select子句的类型)
        - SIMPLE(简单SELECT,不使用UNION或子查询等)
        - PRIMARY(查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)
        - UNION(UNION中的第二个或后面的SELECT语句)
        - DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)
        - UNION RESULT(UNION的结果)
        - SUBQUERY(子查询中的第一个SELECT)
        - DEPENDENT SUBQUERY(子查询中的第一个SELECT,取决于外面的查询)
        - DERIVED(派生表的SELECT, FROM子句的子查询)
        - UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)
    (2) type(MySQL在表中找到所需行的方式,又称“访问类型”)
        - ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行
        - index: Full Index Scan,index与ALL区别为index类型只遍历索引树
        - range:只检索给定范围的行,使用一个索引来选择行(阿里要求最少)
        - ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值(阿里建议最好达到)
        - eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件
        - const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system
        - NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
    (3) possible_keys:查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用
    (4) Key: key列显示MySQL实际决定使用的键(索引)
    (5) key_len: 表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的)
不损失精确性的情况下,长度越短越好
    (7) ref: 上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
    (8) rows: MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数
    (9) Extra
        - Using where:列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤
        - Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询
        - Using filesort:MySQL中无法利用索引完成的排序操作称为“文件排序”
        (如果出现以上的两种的红色的Using temporary和Using filesort说明效率低)
        - Using join buffer:改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。
        - Impossible where:这个值强调了where语句会导致没有符合条件的行。
        - Select tables optimized away:这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行

4、建立联合索引A B C

1.where A B C 走到B就中止了,什么原因?
    - A= B< C=, 这时候索引走A B,由于B是范围查询(B IN()同理),导致C不走索引
2.where C B A 会走索引吗
    - 会的,MySQL有做排序优化,A B C都能走索引

3.1.3 事务和MVCC多版本并发控制

1、事务是什么?它有什么特性?隔离级别?如何设置MySQL事务隔离级别?

1.事务是一系列的数据库操作,是数据库应用的基本单位。只有 InnoDB 引擎支持事务,四个特性如下:

- 原子性(Atomic),要么全部执行,要么全部不执行;
- 一致性(Consistency),事务的执行使得数据库从一种正确状态转化为另一种正确状态;
- 隔离性(Isolation),在事务正确提交之前,不允许把该事务对数据的任何改变提供给其他事务;
- 持久性(Durability),事务提交后,其结果永久保存在数据库中

2.MySQL 中有四种事务隔离级别,分别是:

- read uncommited,未提交读,读到未提交数据;
- read committed,已提交读(不可重复读),两次读取到的数据不一致;
- repetable read,可重复读;(默认)
- serializable,串行化,读写数据都会锁住整张表,数据操作不会出错,但并发性能极低,很少用到;

3、设置MySQL事务隔离级别 
mysql.cnf 文件里设置的(默认目录 /etc/my.cnf),在文件的文末添加配置:transaction-isolation = REPEATABLE-READ

2、MVCC多版本并发控制

https://blog.youkuaiyun.com/SnailMann/article/details/94724197 

1.作用:MVCC在MySQL InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读;(乐观锁的一种实现)

2、什么是MySQL InnoDB下的当前读和快照读?
- 当前读(悲观锁的实现)
像select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁)这些操作都是一种当前读,为什么叫当前读?就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁
- 快照读(MVCC)
像不加锁的select操作就是快照读,即不加锁的非阻塞读;快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读;之所以出现快照读的情况,是基于提高并发性能的考虑,快照读的实现是基于多版本并发控制,即MVCC,可以认为MVCC是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销;既然是基于多版本,即快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本

3、在数据库中,因为有了MVCC,所以我们可以形成两个组合:
1.MVCC + 悲观锁(MVCC解决读写冲突,悲观锁解决写写冲突)
2.MVCC + 乐观锁(MVCC解决读写冲突,乐观锁解决写写冲突)

4、MVCC原理(依赖 3个隐式字段,undo日志 ,Read View 来实现)
- 3个隐式字段
    - DB_TRX_ID:6byte,最近修改(修改/插入)事务ID:记录创建这条记录/最后一次修改该记录的事务ID
    - DB_ROLL_PTR:7byte,回滚指针,指向这条记录的上一个版本(存储于rollback segment里)
    - DB_ROW_ID:6byte,隐含的自增ID(隐藏主键),如果数据表没有主键,InnoDB会自动以DB_ROW_ID产生一个聚簇索引
    - 实际还有一个删除flag隐藏字段, 既记录被更新或删除并不代表真的删除,而是删除flag变了

- undo log
    - insert undo log:代表事务在insert新记录时产生的undo log; 只在事务回滚时需要,并且在事务提交后可以被立即丢弃
    - update undo log:事务在进行update或delete时产生的undo log; 不仅在事务回滚时需要,在快照读时也需要;所以不能随便删除,只有在快速读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除
对MVCC有帮助的实质是update undo log ,undo log实际上就是存在rollback segment中旧记录链,流程如下:
1.比如有一个事务插入person表插入了一条新记录,记录如下,name为Jerry, age为24岁,隐式主键是1,事务ID和回滚指针,我们假设为NULL;
现在来了一个事务1对该记录的name做出了修改,改为Tom

2.现在来了一个事务1对该记录的name做出了修改,改为Tom
- 在事务1修改该行(记录)数据时,数据库会先对该行加排他锁
- 然后把该行数据拷贝到undo log中,作为旧记录,既在undo log中有当前行的拷贝副本
- 拷贝完毕后,修改该行name为Tom,并且修改隐藏字段的事务ID为当前事务1的ID, 我们默认从1开始,之后递增,回滚指针指向拷贝到undo log的副本记录,既表示我的上一个版本就是它
- 事务提交后释放锁;

 3.又来了个事务2修改person表的同一个记录,将age修改为30岁
- 在事务2修改该行数据时,数据库也先为该行加锁
- 然后把该行数据拷贝到undo log中,作为旧记录,发现该行记录已经有undo log了,那么最新的旧数据作为链表的表头,插在该行记录的undo log最前面
- 修改该行age为30岁,并且修改隐藏字段的事务ID为当前事务2的ID, 那就是2,回滚指针指向刚刚拷贝到undo log的副本记录
- 事务提交,释放锁

不同事务或者相同事务的对同一记录的修改,会导致该记录的undo log成为一条记录版本线性表,既链表,undo log的链首就是最新的旧记录,链尾就是最早的旧记录

在事务2修改该行数据时,数据库也先为该行加锁
然后把该行数据拷贝到undo log中,作为旧记录,发现该行记录已经有undo log了,那么最新的旧数据作为链表的表头,插在该行记录的undo log最前面
修改该行age为30岁,并且修改隐藏字段的事务ID为当前事务2的ID, 那就是2,回滚指针指向刚刚拷贝到undo log的副本记录
事务提交,释放锁
3. Read View(读视图)
- Read View就是事务进行快照读操作的时候生产的读视图(Read View),在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被分配一个ID, 这个ID是递增的,所以最新的事务,ID值越大)
- Read View遵循一个可见性算法,主要是将要被修改的数据的最新记录中的DB_TRX_ID(即当前事务ID)取出来,与系统当前其他活跃事务的ID去对比(由Read View维护),如果DB_TRX_ID跟Read View的属性做了某些比较,不符合可见性,那就通过DB_ROLL_PTR回滚指针去取出Undo Log中的DB_TRX_ID再比较,即遍历链表的DB_TRX_ID(从链首到链尾,即从最近的一次修改查起),直到找到满足特定条件的DB_TRX_ID, 那么这个DB_TRX_ID所在的旧记录就是当前事务能看见的最新老版本
- 三个全局属性:
    - trx_list:一个用来维护Read View生成时刻系统正活跃的事务ID数值列表
    - up_limit_id:记录trx_list列表中事务ID最小的ID
    - low_limit_id:ReadView生成时刻系统尚未分配的下一个事务ID,也就是目前已出现过的事务ID的最大值+1

注: MVCC只作用于以下两个隔离级别:
- read committed,已提交读(不可重复读),两次读取到的数据不一致;
- repetable read,可重复读;(默认)

5、事务除了MVCC,还可以通过其他什么锁实现
    共享锁
    排它锁
    意向锁
        排他
        共享
    行锁表锁
    间隙锁(InnoDB存在)
        概念:id为1 3 5 7 这四条数据,查询1-7范围,1-7都会被加锁,2 4 6在1-7范围,但是不存在,这些被成为间隙
        危害:查找1-7时,即使不存在2,也会无辜被锁住,这时无法插入2
        解决:业务采用逻辑删除,非物理删除

3.1.4 读写分离

1、MySQL主从复制原理

(1)半同步复制,即semi-sync复制(解决主库数据丢失问题)
主库写入binlog日志之后,会将强制此时立即将数据同步到从库,从库将日志写入自己本地的relay log之后,接着会返回一个ack给主库,主库接收到至少一个从库的ack之后才会认为写操作完成了
(2)并行复制(解决主从同步延时问题):从库开启多个线程,并行读取relay log中不同库的日志,然后并行重放不同库的日志,这是库级别的并行

2、如何解决主从延迟导致生产环境问题

1、并发方面优化:
(1)分库,将一个主库拆分为4个主库,每个主库的写并发500/s(2000/4=500),此时主从延迟可以忽略不计
(2)开启Mysql并行复制,多个库并行复制,如果说某个库的写入并发就是特别高,单库写并发达到了2000/s,并行复制还是没意义。28法则,很多时候比如说,就是少数的几个订单表,写入了2000/s,其他几十个表10/s。
2、代码层面的优化:
(1)重写代码,写代码的同学,要慎重,当时我们其实短期是让那个同学重写了一下代码,插入数据之后,直接就更新,不要查询
(2)实时性要求的业务读强制走主库,从库只做灾备,备份。
(3)优化SQL,避免慢SQL,减少批量操作,建议写脚本以update-sleep这样的形式完成
3、架构层面的优化:
(1)尽量采用短的链路,也就是主库和从库服务器的距离尽量要短,提升端口带宽,减少binlog传输的网络延时。
(2)提高从库机器的配置,减少主库写binlog和从库读binlog的效率差。

3、实现方式-Cannal

Cannal的好处在于对业务代码没有侵入,因为是基于监听binlog日志去进行同步数据的。实时性也能做到准实时,其实是很多企业一种比较常见的数据同步的方案。实际项目我们是配置MQ模式,配合RocketMQ或者Kafka,Canal会把数据发送到MQ的topic中,然后通过消息队列的消费者进行处理。可以同步到Redis、Hbase、Elasticsearch等。
别再翻手册了!用Materials Studio的Forcite模块,5步搞定复杂溶剂的溶解度参数计算 本文详细介绍了如何使用Materials Studio的Forcite模块,通过5个步骤快速计算复杂溶剂的溶解度参数。从分子建模、结构优化到分子动力学采样,再到最终的内聚能密度计算,该方法大幅提升了石油化工和高分子材料研发中的效率,避免了传统手册查阅和实验的繁琐过程。 阅读详情

相关推荐

传感器模块的电路艺术:从引脚定义到系统集成的设计哲学

本文深入探讨传感器模块的电路设计艺术,从引脚定义到系统集成的完整设计哲学。重点解析电源管理、信号处理及I2C通信协议等核心电路原理,分享多模块协同中的电源架构、信号完整性和接地策略,为硬件工程师提供实用的系统级设计思维与实战案例。

o1p2q3r的博客 223

DM数据事务管理

DM数据事务管理

xiaoke_2013的博客 1589

二元交叉熵:分类模型概率校准的数学根基

二元交叉熵(BCE)是二分类任务中实现概率校准的核心损失函数,其本质源于最大似然估计与KL散度,确保模型输出具备真实可解释的概率意义。相比均方误差(MSE)或Hinge Loss,BCE强制优化预测分布与真实伯努利分布之间的信息差异,使p=0.8真正对应约80%的正例发生率,支撑风控、医疗、推荐等高信度场景的阈值决策。它不只影响训练收敛,更决定部署后概率的业务可信度——这正是Focal Loss等变体无法替代其基础地位的根本原因。理解BCE,就是理解分类模型如何从‘打分器’进化为‘概率契约签署者’。

congli3478的博客 1336

解决可见性的方案有哪几种,你都知道吗???

如何处理线程的可见性呢??? volatile/ synchronized/ reentrantLock

weixin_42373116的博客 872

【Unity终极奥义】Unity打包去掉启动画面Logo,无需破解,一学就会

大家都知道Unity打包的应用在启动的时候都会有一个默认的UnityLogo。 而且这个Logo使用升级版和破解版都是可以随意清除和更换的。 但是Unity个人版是无法通过Unity的打包设置去进行更换的。 那今天就教大家一个使用个人普通版更换Unity启动画面Logo的方法!一起来看一下吧!

努力前行,总会成为自己心中的那道光 8万+

Claude Code 100个真实案例 - 用AI绘制CAD机械图纸(工程师看了直呼内行)

本案例展示如何使用 Claude Code 配合 Python 的 `ezdxf` 库,从零开始生成专业级 CAD 机械图纸。我们将绘制一个完整的法兰盘零件图,包含主视图、俯视图、标注尺寸、粗糙度标记和标题栏,最终生成标准 DXF 文件,可直接在 AutoCAD 或 FreeCAD 中打开编辑。

yueyeguzhuo的专栏 896

达梦数据库报错错误代码汇总-26年6月更新

达梦数据库报错代码查询汇总,错误代码

牛排煎黑椒的博客 3万+

【项目实战】DevOps制品管理之JFrog Artifactory介绍

JFrog Artifactory是一款领先的二进制软件制品仓库管理工具,由JFrog公司开发。

奶爸的编程之路,也就一周冷个三天 1355

InnoDB MVCC RR隔离级别下的数据可见性总结

一、背景 熟悉数据库隔离级别的人都知道,在RR(可重复读)隔离级别下,无论何时多次执行相同的SELECT快照读语句,得到的结果集都是完全一样的,即便两次SELECT语句执行期间,其他事务已经改变了该查询结果并已经提交。 对于这一机制的实现原理,网上常见的一种解释如下: ####MVCC在MySQL的InnoDB中的实现 在InnoDB中,会在每行数据后添加两个额外的隐藏的值来实现MVCC,...

孔子说 720

华为OD机试真题2025双机位A卷 Java&Go 实现【采购订单】

在一个采购系统中,采购申请(PR)需要经过审批后才能生成采购订单(PO)。每个PR包含商品的单价(假设相同商品的单价一定是一样的)及数量信息。系统要求对商品进行分类处理:单价高于100元的商品需要单独处理,单价低于或等于100元的相同商品可以合并到同一采购订单PO中。针对单价低于100的小额订单,如果量大可以打折购买。

MISAYAONE的博客 1259

【NodeRed】node-red-contrib-opcua实现PLC读写

在之前的博文【Node-RED】node-red-contrib-opcua-server模块使用(1)中,我们介绍了用node-red-contrib-opcua-server模块实现OPCUA服务端的,以及二次开发的内容。本节博文中我们采用官方社区自带的node-red-contrib-opcua组件开展对OPCUA客户端的介绍,详细阐述用该组件中OpcUa-Client节点实现客户端对PLC的读写,以及实现过程中遇到的问题。由于官方社区中并没有找到该组件的介绍实例,这也是本博文编写的第1个原因。

weixin_48618536的博客 958

达梦数据库事务管理-MVCC

也就是说,不管事务执行多长时间,事务内部看到的数据是不受其它事务影响的,根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。根据事务隔离级的不同,在事务启动时(串行化),或者语句执行时(读提交),收集这一时刻所有活动事务,并记录系统中即将产生的事务号NEXT_TID。这种MVCC机制,要求事务根据当前正在活动事务的视图,依据上述的链式版本,构成可见的记录集合。对于每一个新事务,这个活动事务视图包含了当前还没有结束的事务的事务ID,也就是说,对于每一个新事务,都维护了一个数组。

qq_18821871的博客 769

第10章《VTK自定义部件Widget》

是用于交互式操作 3D 场景的组件,例如移动对象、调整尺寸、创建标注等。VTK 提供了一些内置的 Widget,如。,用户可以点击鼠标,在 3D 场景中放置一个点。负责绘制一个点,并控制其颜色、大小等。,可用于 3D 标注、对象拾取等应用!等,但在某些应用中,我们需要。这样,我们就创建了一个。

yumeiguo的博客 523

mysql数据库管理面试题-3

在线数据过滤和数据筛选都是数据分析和数据库查询的重要工具,它们在功能和使用方式上有所区别。在线数据过滤更侧重于交互式数据探索和多维数据分析,而数据筛选则更侧重于静态数据集的快速、精确查询。数据关联是数据库中合并相关数据的强大工具,通过匹配字段,你可以根据不同的条件合并多张表中的数据。结合使用数据关联和数据筛选,你可以构建出复杂的查询,来检索你需要的特定信息。在线数据排序和数据分组是SQL中进行数据分析和报告的基本工具。排序可以用来确定数据的顺序,而分组可以用来汇总和聚合数据。

weixin_41312759的博客 839

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

php面试题mysql如果b>a用a_PHP面试题及答案解析(3)—MySQL数据库

1.mysql_num_rows()和mysql_affected_rows()的区别。mysql_num_rows()和mysql_affected_rows(),这两个函数都作用于 mysql_query($query)操作的结果,mysql_num_rows() 返回结果集中行的数目。mysql_affected_rows() 取得前一次 MySQL 操作所影响的记录行数。mysql_num...

weixin_32631179的博客 550

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

NodeJS全栈开发面试题讲解——P3数据库(MySQL / MongoDB / Redis)

问题编号技术点3.1Node 连接 MySQL,使用 ORM(Sequelize / TypeORM)3.2一对多、多对多关系映射与查询3.3Redis 多场景应用:缓存、限流、队列等3.4Cache-Aside 缓存策略的实现与代码演示3.5事务操作方式 + MySQL ACID 原理。

Theoweb3|优快云 wwh1st|GitHub theoweb3|TG theo_liu|X theoweb33|gmail wwh9th 华语区Web3基础设施建设者;Web3开源社区共建者;博客沉淀去中心化等各类工程经验。 1293

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

php面试题mysql如果b%3ea用a_php面试题之——MySQL数据库(基础部分)

mysql_num_rows()mysql_affected_rows()这两个函数都作用于 mysql_query($query)操作的结果,mysql_num_rows() 返回结果集中行的数目。mysql_affected_rows() 取得前一次 MySQL 操作所影响的记录行数。mysql_num_rows()仅对 SELECT 语句有效,要取得被 INSERT,UPDATE 或者 DE...

weixin_33724759的博客 446

数据库sqlite3怎么排顺序_【数据库02】MySQL数据库面试题

一、索引相关1. 索引是个什么样的数据结构呢?索引的数据结构和具体存储引擎的实现有关, 在MySQL中使用较多的索引有Hash索引,B+树索引等,而我们经常使用的InnoDB存储引擎的默认索引实现为:B+树索引.2. Hash索引和B+树所有有什么区别或者说优劣呢?首先要知道Hash索引和B+树索引的底层实现原理:(我先叙述我个人理解,不要死记硬背,一定要理解,这里面试官很容易深问)ha...

weixin_39618121的博客 411

3 MYSQL中的六大约束是什么_有关数据库的一些面试题

1、在一个查询中,使用哪个关键字能够去重复值?使用distinct关键字2、解释存储过程和触发器?存储过程:是一个已编译的SQL语句,不必重新编译,可以重复执行,提高了代码的重用性和数据库的性能;触发器:是一种特殊的存储过程,不由用户直接调用,创建触发器时会对其进行定义,以便在对特定的表或列做特定的操作时执行。*3、SQL Server中的锁机制有哪些,有什么好处?有行级锁、表级锁优化数据的并行访...

weixin_39928480的博客 205

PHP面试题及答案解析(3)—MySQL数据库

1.mysql_num_rows()和mysql_affected_rows()的区别。 mysql_num_rows()和mysql_affected_rows(),这两个函数都作用于 mysql_query($query)操作的结果,mysql_num_rows() 返回结果集中行的数目。mysql_affected_rows() 取得前一次 MySQL 操作所影响的记录行数。mysql_n...

weixin_30247159的博客 3165

最新数据库基础笔记(MySQL)3 —— 基础操作,线程面试题及答案

由于文案过于长,在此就不一一介绍了,等等知识详解。本知识体系适合于所有Java程序员学习,关于以上目录中的知识点都有详细的讲解及介绍,掌握该知识点的所有内容对你会有一个质的提升,删除表 ( drop )drop table 表名;( 如果表不存在,则会报错 );drop table if exits 表名;( 如果该表存在的话,将它删除 , 可以防止报错)表结构操作 ( alter )删除表中字段alter table 表名 drop ( column 可写可不写 ) 字段;

2401_83977689的博客 940

数据库sqlite3怎么排顺序_MySQL数据库面试题(2020最新版)(二)

作者:ThinkWon来源:https://blog.csdn.net/ThinkWon/article/details/104778621事务1. 什么是数据库事务?事务是一个不可分割的数据库操作序列,也是数据库并发控制的基本单位,其执行的结果必须使数据库从一种一致性状态变到另一种一致性状态。事务是逻辑上的一组操作,要么都执行,要么都不执行。事务最经典也经常被拿出来说例子就是转账了。假如小明要给...

weixin_36212539的博客 442

字节数仓面试题(3年内)

本文整理了18篇小红书数仓开发面试题汇总,涵盖数据仓库核心技术知识点。主要内容包括:1)数据处理流程(Kafka到Hive、Spark/MapReduce原理);2)SQL优化(索引、B+树、执行计划);3)数仓建模(分层设计、星型/雪花模型);4)性能调优(数据倾斜处理、小文件优化);5)算法题(二分查找、字符串处理等)。特别聚焦Spark核心机制(RDD、Shuffle、AQE)、Hive优化以及Flink实时处理,适合1-3年经验的数仓开发者准备面试使用。

数据在准,在稳,架构可拓。 1022

2024年Java最全十年数据库专家,呕心力作MySQL技术精粹,薪资直涨3K其实很轻松,mybatis企业必问面试题

可能有人会问我为什么愿意去花时间帮助大家实现求职梦想,因为我一直坚信时间是可以复制的。我牺牲了自己的大概十个小时写了这片文章,换来的是成千上万的求职者节约几天甚至几周时间浪费在无用的资源上。上面的这些(算法与数据结构)+(Java多线程学习手册)+(计算机网络顶级教程)等学习资源本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录需要这份系统化的资料的朋友,可以点击这里获取。

2401_84584238的博客 1001

2024年大数据最全《大型数据库技术》MySQL数据库安装配置及基础使用(3),大数据开发面试题2024基础

创建一张雇员表,命名为employee,包括如下字段:雇员工号(从86001开始递增),姓名,性别,生日,部门名称。INSERT INTO employee VALUES(“0”, “陆振宇”, “男”, “1999.8.15”, “研发部”);INSERT INTO employee VALUES(“0”, “张三”, “男”, “1997.6.20”, “研发部”);INSERT INTO employee VALUES(“0”, “李四”, “男”, “1998.7.18”, “人事部”);

2401_84586572的博客 584

腾讯高工亲授“MySQL学习方法”【思维导图+学习笔记+实战文档+面试题库】让你站在数据库领域的顶峰 笑傲江湖!

前言 MySQL近两年一直稳居第二,随时有可能超过Oracle计晋升为第一名,因为MySQL的性能一直在被优化,同时安全机制也是逐渐成熟,更重要的是开源免费的。 目前大部分的互联网的首选也仍然是MySQL,所以作为一名开发人员,掌握好MySQL的使用是非常有必要的,那么如何能够达到“精通”MySQL的程度,那就需要耗费不少心思了。那么如何学习MySQL呢?今天就来好好谈谈。 下面介绍我学习MySQL的三个步骤,一天就搞定了MySQL,让我顺顺利利拿下了天猫的offer。 这三个步骤里,包括了很多文

bieber007的博客 197
上一篇: 本地Docker 安装MySQL、Redis、MongoDB、PgSQL等
下一篇: 《面试题》2、Java基础框架
CarsonBigData
博客等级 码龄9年 8316粉丝 166原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值