-
docker是怎么实现资源隔离的?
docker容器本质上是宿主机上的进程。
docker利用linux的namespacce实现资源隔离,利用cgroups实现资源限制。
同一个namespace之内可以看到相同的全局资源,而不同的namespace不能,可以在创建进程clone的时候指定进程的namespace,或者通过setns等函数来做。
cgroups和namespace类似,但是是做资源限制用的。 -
临键锁了解吗
临键锁即next-key,在mysql的innodb里是为了防止幻读的。
即防止某次事务的两次当前读因为其他事务的插入操作出现不同的结果集合。
当我们以非唯一索引进行等值查询的时候,会在记录行的前面加上临键锁,在记录行的后面加上间隙锁。
如果是唯一索引,则临键锁会退化成行锁。
如果等值查询不存在,则会在查询值所在的区间上,加一个间隙锁。
如果查询条件很多,可能会加上多个临键锁。
如果查询字段没有索引,会升级为表级锁。
-
什么时候会进行锁表?
表级锁分为三类: -
表锁:对非索引字段进行等值查询,并且是当前读的时候,innodb会加上表锁
-
mdl锁(元数据锁):当对表结构做更改时,比如加字段时,mysql会自动加上表锁
-
意向锁:意向锁是为了在后续某个操作想加表锁的时候,方便它判断这张表是否已经被锁定了(无论是行级锁还是表级锁,都会锁定意向锁)
-
什么是悲观锁,什么是乐观锁:
悲观锁是说,获得锁之后,直到事务结束才会释放锁,以悲观的方式防止数据被改动。(可能会形成死锁,实现简单)
乐观锁一般需要用户自己实现,比如为记录加上版本号,通过检查上次读的版本号和本次读的版本号是否不同,来判断是否已经被改了。(并发度高,不会形成死锁) -
数据库怎么解决死锁?
打开innodb_deadlock_detect,会在形成死锁的时候返回一个异常,在拿到异常的时候重试事务即可。会释放掉已经拿到的锁,这样就ok啦。 -
char 和 varchar的区别
char最大长度255,varchar最大长度65535.
char是定长的(多余的部分会加上隐藏空格),varchar是不定长的。
char是定长的因此可以取,但是varchar则先要拿到长度。
varchar适合变长的字符串,但是char适合定长的字符串。如果字符串长度很短,一般用varchar可能比较好。 -
索引的类型
从索引的底层存储结构来说:
hash索引
有序数组
B+树索引
聚集索引/二级索引
唯一索引/常规索引
联合索引/前缀索引
覆盖索引
-
索引失效的情况
-
联合索引不遵从最左前缀法则
-
在索引字段上使用函数
-
匹配字符串不叫引号(隐式转换)
-
范围查询会导致部分失效
-
当mysql觉得走全表扫描比走索引更快的适合(比如范围查询,走二级索引还要回表,直接全表扫描可能更快)
-
字符串匹配的百分号在最前面
-
MyISAM的B+树索引和InnoDB的B+树索引的区别?
MyISAM的B+树索引的叶子节点存放的是数据所在的地址,而InnoDB存放的是行数据本身。 -
为什么B+树索引?
hash虽然快,但是范围查询和排序都无法很好支持,需要全表扫描。
B树的数据存放在非叶子节点上,会导致一个页里只能存放更少的索引项,索引项就会占用更多的页,提升了磁盘IO次数。而且因为在非叶子节点上存数据,会导致
顺序查找很麻烦 -
B+树为什么底层有双向指针?
-
支持范围查找,更快
-
某个页删除的行数据足够多的时候,该页可能会和相邻页进行页合并,此时就需要双向指针来操作链表
-
什么是覆盖索引?什么是索引下推?
要查询的字段从索引里就能拿到。
索引下推:在查询索引的同时也用索引进行过滤,减少回表查询次数。5.6以前的做法是回表完了由server层进行过滤。 -
怎么直到扫描行数?
事先不知道,但是根据统计信息来预估,这个统计信息就是索引的区分度。 -
redolog和binlog
redolog是innodb带的,用于崩溃恢复
binlog用于主从复制和数据恢复。
redo log是循环写的,binlog是追加的。
redo log物理日志,binlog是逻辑日志。
bin log不是crash safe的!!?
为啥?因为redo log在bufferpool刷盘之后会删掉物理日志,那么就能根据redo log来弄 -
两阶段提交
在写入bufferpool后,先在redo log里记录操作并设置为prepare状态,然后写binlog,最后在redo log里写commit状态。
如果只写一次,会导致崩溃恢复的时候主从不一致。
三种情况:1. redo log commit了,那么不用管,直接redo log恢复 2. redo log prepare,并且trx id在binlog里找不到,那么应当回滚,如果找到,直接提交 -
redo log的刷盘时机?
在进行事务commit的时候进行刷盘,刷盘之后涉及两阶段提交。 -
mysql执行很慢,怎么回事?
-
系统资源不足,如内存不够导致大量的页错误,或者网络带宽不够
-
等待表锁或者行锁
-
没有走索引
-
虽然走了索引但是回表次数太多了,这个时候一般可以考虑建立联合索引,以达到覆盖索引的作用
怎么看走了哪个索引?
explain,关键字段:id,possible keys, key, extra, filter;
怎么解决?
有时候不走索引我们要强制force index让它走索引。。
18:drop, truncate和delete的区别
delete操作会写到undo log日志里以做回滚。
truncate则是情况表空间,并且不写undo log日志,因此truncate是无法回滚的。
drop会把表结构也删掉。
19.大表查询为什么不爆内存?
边读边发,用next buffer来存,因此可能会使事务迟迟无法结束但是不会爆内存
- 临时表只对当前session可见
21.为什么不用memory而用redis
持久性问题,锁的粒度问题(只支持表锁)
-
主从复制(主备复制)
备库:changemaster
悲库:start slave
备库接受主库发来的binlog,然后将binlog的内容写到备库的relaylog(中转日志),再对relaylog做重放 -
mysql为什么会抖一下?
后台线程定时刷bufferpool的脏页,或者bufferpool满了,根据lru进行页淘汰的时候也会写磁盘,这都会导致mysql变慢