Contents

7.1. 01.MySQL面试宝典

7.1.1. 自我介绍

自我介绍的三个要素。

第一点: 自我认知的能力,要对自己有个全方位的人生,营造一种轻松的聊天氛围,建立真诚互信的关系。

第二点: 对岗位的认知能力,捋清晰问题的解决思路,推销自己解决问题相应的操作,在对资源的利用方面的办法。资源包括:工具资源、人脉资源….

第三点:分清主次,捡重要的说,面试过程中要学会听清对方所提问的问题,不要在不了解问题的基础上畅所欲言。 而且在回答问题时,要学会摸清对方心理,捡重点来阐述,面试官看重的是你是否是一个有大局观、测分清主次的人。 今后当你向领导汇报问题时,可以协助领导以最快的速度了解目前的现状,早下决策。

不要有频繁跳槽的经历,DBA从事的是维护公司核心数据库安全与业务稳定性的任务,如果出现经常跳槽的现象, 是没有公司敢要你的,技术更新换代很迅速,而且学习的过程是需要积累与沉淀的。

跳槽太多不利于你静下心来深入研究技术知识,你可能永远停留在最初的阶段,那么很多优秀的岗位、有货的薪资都将与你擦肩而过。 所以希望在数据库领域从事的年轻人,不要太浮躁,踏实做事,认真做人,稳步前进。

7.1.2. 技术问答

问题1 你目前接触的MySQL 版本是什么? 除了官方版本, 还接触过其他的MySQL 分支版本吗?

解答思路:

首先可以谈谈产生分支的原因。许多开发人员认为有必要将其拆分成其他项目,并且每个分支项目都有自己的专长。
该需求和OracIe 对核心产品增长缓慢的担忧, 导致出现了许多开发人员感兴趣的子项目和分支。

介绍一下三个流行的MySQL分支:Drizzle 、ManaDB 和Percona Server(包括XtraDB引更细节化展开说明各个分支的特点。ManaDB 不仅是MySQL 的替代品, 主要是创新和提
高了MySQL 自有技术。新功能介绍如下:

multi-source replication 多源复制、表的并行复制
(MySQL5.7版本中也加入该特性)、galera cluster 集群、spider水平分片和TokuDB 存储引擎。
XtraDB 是lnnoDB 存储引擎的增强版, 可用来更好地发挥最新的计算机硬件系统性能,还包含在高性能模式下的新特性。
它可以向下兼容, 因为它是在InnoDB 基础上构建的,所以有更多的指标和扩展功能。而且它在CPU 多核的条件下,
可以更好地使用内存, 将数据库性能提到更高。
Drizzle 与MySQL 的差别就比较大了,并且不能兼容,如果想运行此环境,就需要重写一些代码了。

问题2 MySQL主要的存储引擎MyISAM和InnoDB的不同之处?

解答思路:
可以从五个方向去介绍。

·事务的支持不同(InnoDB 支持事务、MyISAM 不支持事务)

·锁粒度(lnnoDB 行锁应用、MylSAM 表锁)

·存储空间(InnoDB 既缓存索引文件,又缓存数据文件,My1SAM 只能缓存索引文件)

·存储结构(MylSAM:数据文件的扩展名为.MYDmyData,索引文件的扩展名是.MYI myIndex; InnoDB:所有的表都保存在同一个数据文件里面,即.Ibd)

·统计记录行数(MyISAM:保存有表的总行数,select count(*) from table 会直接取出该值
               InnoDB:没有保存表的总行数, select count(*) from table 会遍历整个表,消耗相当大)

问题3 数据表类型有哪些

解答思路:
MyISAM、InnoDB、HEAP、BOB,ARCHIVE,CSV等。

       MyISAM:成熟、稳定、易于管理,快速读取。一些功能不支持(事务等),表级锁。
       InnoDB:支持事务、外键等特性、数据行锁定。空间占用大,不支持全文索引等。

问题4 如何设计一个高并发的系统

① 数据库的优化,包括合理的事务隔离级别、SQL语句优化、索引的优化

② 使用缓存,尽量减少数据库IO

③ 分布式数据库、分布式缓存

④ 服务器的负载均衡

问题5 Myql中的事务回滚机制概述

事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位,事务回滚是指将该事务已经完成的对数据库的更新操作撤销。

要同时修改数据库中两个不同表时,如果它们不是一个事务的话,
当第一个表修改完,可能第二个表修改过程中出现了异常而没能修改,此时就只有第二个表依旧是未修改之前的状态,
而第一个表已经被修改完毕。而当你把它们设定为一个事务的时候,当第一个表修改完,第二表修改出现异常而没能修改,
第一个表和第二个表都要回到未修改的状态,这就是所谓的事务回滚

问题6 SQL语言包括哪几部分?每部分都有哪些操作关键字?

数据定义:Create Table,Alter Table,Drop Table, Craete/Drop Index等

数据操纵:Select ,insert,update,delete,

数据控制:grant,revoke

数据查询:select

问题7 介绍一下InnoDB的体系结构

解答思路:

谈及InnoDB的体系结构,首先要考虑MySQL的体系结构,分为MySQL的server层和存储引擎层两部分。 先要跟面试官聊清楚MySQL的整体方向,然后再去涉及InnoDB系统结构,建议从三方面介绍InnoDB体系结构: 内存线程磁盘

内存中包含 insert_buffer、data_buffer、index_buffer、redo_log_buffer、double_write。
内存刷新到磁盘的机制: redo log buffer 、脏页、binlig cache 的刷新条件
各种线程的作用: master_thread、purge_thread、redo log thread、read thread、write thread、page cleaner thread。
磁盘中存放的数据文件: redo log、 undo log、binlog。

问题8 MySQL有哪些索引类型?

解答思路: 可以从三个角度去谈,从数据结构角度上可以分为B+tree索引hash索引fulltext索引(InnoDB、 MyISAM都支持)

其次从存储角度上可以分为聚集索引非聚集索引

从逻辑角度上可以分为primary keynormal key单列复合和覆盖索引

问题9 MySQL binlog有几种格式? 生产中你用哪种?各自有什么特点?

第一种,statement格式

优点:不需要记录每一行的变化,减少了binlog日志量,节约了I/O,提高了性能。
缺点:当使用一些特殊函数,或者夸库操作时容易丢失数据。

注:在生产中不建议使用。

第二种,row格式。

优点:清晰记录每行的数据信息,不会出现跨库丢数据的情况,安全性非常高。
缺点:当内容记录到日志中时,都将以每行的修改来记录,会产生大量的binlog,网络开销也比较大。

注:生产中推荐使用。

第三种,mixed格式。

MySQL5.1的一个过渡版本,DDL语句会记录成statement,DML会记录成row。

注:生产中不建议使用。

问题10 MySQL 主从复制的具体原理是什么?

解答思路:

主服务器把数据更新记录到二进制日志中,从服务器通过I/O thread向主库发起binlog请求, 主服务器通过I/0 dump thread把二进制日志传递给从库,从库通过I/O thread记录到自己的中继日志中, 然后通过SQL thread 应用中继日志中SQL的内容。

问题11 MySQL 主从延迟的原理是什么? 如何监控主从延迟,如何解决主从延迟问题?

解答思路:

核心延迟问题: 主库可以并发写入,但从库只能通过单SQL thread完成任务,(MySQL 5.7之前),这是出现主从延迟的最核心原因。

其他方面:

(1)MySQL主从之间的同步本来不是实时同步的,是异步的同步,也就是说,主库提交事务之后,从库再执行一遍。
(2)在主库上对没有索引大表的列进行delete或者update的操作。
 (3) 从库的硬件配置没有主库的好,经常忽略从库的重要性。
 (4) 网络抖动导致I/O线程复制延迟。

针对如何监控MySQL replication复制延迟的问题,

我们可以通过第三方工具(业界中的瑞士军刀,perconna-toolkit)中的pt-heartbeat命令进行主从延迟监控。

使用脚本进行监控:
 传统方法,通过比较主从服务器之间的position号的差异值。
 还可以通过查看seconds_behind_master估算一下主从延迟时间。

解决延迟的方法:

(1)使用MySQL5.7的并行复制功能。在5.6版本中就有了并行的概念, 但其中的并行复制是基于库级别的,
即slave-parallel-type=database 。

但这种模式下,只是基于多库少表的情况,并不适用于真实的生产环境下。在MySQL5.7版本中,真正实现了基于组提交的并行复制,
简单说就是主库并行执行SQL语句,从库也可以通过多个workers 线程并发执行relay log 中主库
提交的事务。想要开启MySQL5.7的并行复制,可以在从库设置参数slave-parallel-workers>0,
并把5.7版本中新添加的slave-parallel_type 参数设置为LOGICAL_CLOCK。

该参数有DATABASE 和LOGICAL_CLOCK 两个值。MySQL5.6默认是DATABASE0


(2) 可以采用Percona公司的peercona-xtradb-cluster (简称PXC 架构),这种架构下可以实现多节点写入,达到实时同步。

(3) 业务初期规划时,就要选择合适的分库、分表策略,避免单表或者单库过大,带来额外的复制压力,从而带来主从延迟的问题。

(4) 避免一些无用的I/0消耗,可以增加高转速的磁盘、SSD或者PCIE-SSD设备。

(5) 阵列级别要选择RAID10, raid cache策略要采用WB,坚决不要采用WT。

(6) I/O 调度要选择deadline模式。

(7) 适当调整buffer pool的大小。

(8) 避免让数据库进行各种大量运算,要记住数据库只是用来存储数据的,让应用端多分担些压力,或者可以通过缓存来完成。

问题12 数据库中的双一是什么?

两个参数着手分析。一个是 sysn_binlog=1,另一个就是 innodb_flush_log_at_trx_commit=1

innodb_flush_log_at_trx_commit=1sync_binlog两个参数是控制MySQL磁盘写入策略以及数据安全性的关键参数。

innodb_flush_log_at_trx_commit设置为1,每次事务提交时,MySQL都会把log buffer的数据写入log file,并且刷到磁盘中。

sync_binlog=N(N>0),MySQL在每写N次二进制日志binary log时,会使用fdatasync()函数将它的写二进制日志binary log同步到磁盘中。

问题13 如果实施大表DDL语句才能把性能影响降到最低?

解答思路:

我们可以先通过传统方法导入/导出数据,新建一张与原表一样的表结构,把需要执行的DDL语句在无数据的新表中执行,然后把老表中的数据 导入导入到新表中,最后把新表改成老表的名字。

也可以通过第三方工具(percona-toolkit)中的pt-online-schema-change命令进行在线操作,对于MySQL5.7版本可以直接在线“online ddl”。

还可以介绍一下MySQL 对大表进行drop table 操作时,可以对数据文件建立硬连接,
这样可以缩短执行时间。依赖的原理: OS HARD LINK。

当多个文件名同时指向同一个INODE时, 这个INODE 的引用数> 1 ,
删除其中任何一个文件名只是删除了一个指针,不会删除数据文件。当INODE的引用数N=1时,
删除文件时需要把这个文件相关的所有数据块清除,所以会比较耗时。

问题14 为什么要为InnoDB表设置自增列做主键?

解答思路:

使用自增列作为主键,写入顺序是自增的,和B+数叶子节点分裂顺序一致,InnoDB表的数据写入顺序能和B+树索引的叶子节点顺序一致时,存取效率是最高的。

问题15 如何优化一条慢SQL语句?

针对SQL语句的优化,我们不要一上来就回答添加索引,这样显得太不专业。我们可以从如下几个角度去分析:

(1) 回归到表的设计层面,数据类型选择是否合理
(2) 大表碎片的整理是否完善
(3) 表的统计信息是不是准确的
(4) 审查表的执行计划,判断字段上面有没有合适的索引。
(5) 针对索引的选择性,建立合适的索引(就又设计大表DDL的操作问题)

问题16 服务器负载过高或者网页打开缓慢,简单说说你的优化思路?

我们可以从优化思路中的四维度模型去阐述。

首先要发现问题的过程,通过操作系统、数据库、程序设计、硬件角度是个维度找到问题所在。
先找到瓶颈点的位置,制定好优化方案,形成处理问题的体系模型。体系定制好之后,在测试环境进行优化方案的测试。
测试环境下如果优化效果很好,再实施到生产环境上。最后做好处理问题的记录,好记性不如烂笔头,多做总结,访客大步前进。

问题17 你接触过哪些MySQL的主流架构?架构应用中有哪些问题需要考虑?

解答思路:

先整体介绍一下你所指的的集群架构:

(1) M-S。
(2) MHA
(3) MM+Keepalived
(4) PXC
(5) 利用中间件ProxySQL配合PXC架构

MHA优缺点:

优点:

(1) 故障切换时,可以自行判断哪个从库与主库的数据最接近,就切换到上面,可以减少数据丢失的风险,保证数据的一致性。
(2) 支持binlog server,可提高binlog传送效率,进一步减少数据丢失风险。
(3) 结合MySQL5.7的增强半同步功能,来确保故障切换时的数据不丢失。

缺点:

(1) 自动切换的脚本太简单了,而且比较老化,建议后期逐渐完善。
(2) 搭建MHA架构,需要开启Linux系统互信协议,所以对于系统安全性来说是个不小的考验。

MM+Keepalived集群的建议:

(1) 一定要完善好切换脚本,Keepalived的切换机制要合理,避免发生切换不成功的现象。
(2) 从库的配置尽量要与主库的一致,绝对不能太差;避免主库宕机时发生切换,新的主库(原来的从库)影响线上业务进行。
(3) 对于延迟的问题,在这套架构中也不能避免。可以改变架构模式,使用PXC完成实时同步功能,基本上可以达到没有延迟。
(4) Keepalived无法解决脑裂的问题,因此在进行服务异常判断时,可以修改判断脚本,通过对第三方节点补充检测来决定是否进行切换,可降低脑裂问题产生的风险。
(5) 采用Keepalived架构,在设置两节点状态时,都要设置成backup状态,而且还都是不抢占模式,通过优先级来决定谁是主库。避免发生脑裂、冲突现象。
(6) 安装好MySQL需要的一些依赖包:建议配置好Yum源,用Yum安装Keepalived即可。

PXC架构的优缺点

优点:

(1) 实现MySQL数据库集群架构的高可用性和数据的强一致性
(2) 完成了真正的多借点读写的集群方案
(3) 改善了传统意义上的主从复制延迟的问题,基本上达到了实时同步。
(4) 对于新加入的节点可以自动部署,无需手动备份,维护起来很方便。
(5) 由于多节点写入,所以发送数据库故障时切换很容易。

缺点:

(1) 新加入的节点开销大,需要复制完整的数据,采用SST传输开销太大。
(2) 任何更新事务都需要全局验证通过,才会在每个节点库上执行。集群性能受限于性能最差的节点,也就是经常说的短板效应。
(3) 因为需要保证数据的一致性,所以在多节点并发写时,锁冲突问题比较严重。
(4) 存在写扩大问题,所有的节点上都会发生写操作。
(5) 只支持InnoDB存储引擎表。
(6) 没有表基本的锁定,执行DDL语句操作会把整个集群锁住,而且也“kill”不了(注:建议使用OSC操作)
(7) 所有的表必须含有主键,否则操作数据时会报错。

问题17 什么是死锁?锁等待?通过数据库哪些表可以监控?

解答思路:

死锁是指两个或多个事务在同一资源上互相占用,并请求加锁时,而导致的恶性循环现象。当多个事务以不同顺序试图加锁同一资源时, 就会产生死锁。

锁等待: MySQL数据库中,不同session在更新同行数据时,会出现锁等待的现象。 重要的三张锁的监控表: innodb_trx、innodb_locks innodb_lock_waits

问题18 你之前处理过MySQL的哪些案例?

逃离不了MySQL的五大知识模块:

体系结构
数据备份与恢复、复制、高可用集群架构和优化,从五个方面着手考虑:

(1) MySQL版本的升级
(2) 处理集群架构中的各种“坑”和问题
(3) 根据公司业务类型,合理设计MySQL库、表和后期架构。
(4) 定期进行灾备恢复演练。
(5) 恢复误删除的数据信息

问题19 对MySQL的锁了解吗?

答:当数据库有并发事务的时候,可能会产生数据的不一致,这时候需要一些机制来保证访问的次序,锁机制就是这样的一个机制。

就像酒店的房间,如果大家随意进出,就会出现多人抢夺同一个房间的情况,而在房间上装上锁,申请到钥匙的人才可以入住并且将房间锁起来,其他人只有等他使用完毕才可以再次使用。

问题20 MySQL都有哪些锁呢?像上面的例子进行锁定岂不是有点阻碍并发效率了?

答:从锁的类别上来讲,有共享锁和排他锁。

共享锁 : 又叫做读锁,当用户要进行数据的读取时,对数据加上共享锁,共享锁可以同时加上多个。

排他锁 : 又叫做写锁,当用户要进行数据的写入时,对数据加上排他锁,排他锁只可以加一个,他和其他的排他锁,共享锁都相斥。

用上面的例子来说就是用户的行为有两种,一种是来看房,多个用户一起看房是可以接受的。一种是真正的入住一晚,在这期间,无论是想入住的还是想看房的都不可以。

锁的粒度取决于具体的存储引擎,InnoDB实现了行级锁,页级锁,表级锁。他们的加锁开销从大到小,并发能力也是从大到小。

问题21 一条sql执行过长的时间,你如何优化,从哪些方面?

1、查看sql是否涉及多表的联表或者子查询,如果有,看是否能进行业务拆分,相关字段冗余或者合并成临时表(业务和算法的优化)。
2、涉及链表的查询,是否能进行分表查询,单表查询之后的结果进行字段整合。
3、如果以上两种都不能操作,非要链表查询,那么考虑对相对应的查询条件做索引。加快查询速度。
4、针对数量大的表进行历史表分离(如交易流水表)。
5、数据库主从分离,读写分离,降低读写针对同一表同时的压力,至于主从同步,mysql有自带的binlog实现 主从同步。
6、explain分析sql语句,查看执行计划,分析索引是否用上,分析扫描行数等等。