把数据库生产账号放在新人文档上,谁之过?
7 年前 Reddit 论坛出现了这么一篇帖子,大学毕业后第一天上班的新手程序员,运行了一份数据库测试脚本,直接把整个生产数据库删掉,CTO 让他有多远滚多远。
我是南哥,相信对你通关面试、拿下Offer有所帮助。
敲黑板:本文总结了MySQL事务、主从复制等常见的面试题!
MySQL事务有四大特性。
SQL标准定义了四种隔离级别,较低级别的隔离通常来说系统开销更低些。
MySQL
默认的事务隔离级别。SQL
超时。并发事务带来的问题主要有四种,可以用上面我们谈到的事务隔离级别来处理。
幻读可以采用我提到的SERIALIZABLE
(可串行化)隔离级别来解决幻读,事务按顺序执行,也就不会有幻读问题。
MySQL也提供了其他方法来处理幻读问题。
死锁是因为多个事务互相占用对方请求的资源导致的现象,要打破这个问题需要回滚其中一个事务,这样另一个事务就能获得请求资源了,而回滚的事务只需要重新执行即可。
InnoDB引擎目前处理死锁的方法是通过持有行级排他锁的数量来判断,持有最少行级排他锁的事务会进行回滚。
MySQL默认隔离级别是可重复读,企业生产一般也是用的这个隔离级别。
查看隔离级别的指令:
select @@tx_isolation
设置隔离级别为可重复读的指令:
set session transaction isolation level repeatable read
面试官:MySQL主从复制了解吧?
回答这个问题前,大家先思考下MySQL主从复制起到了什么作用。知道技术诞生的缘由,技术原理和步骤的整个逻辑推导就很清晰。
MySQL主从复制把数据库数据同步到多台服务器上,同理就可以把读操作分布到多台服务器上,这对于那些读密集型的系统性能提升是很大的。
数据有了多台服务器的备份,就不怕单点故障。我们只需要快速切换到另一台MySQL服务器即可,减少了数据库宕机的时间。
MySQL主从复制主要是利用了主库的Binary Log二进制文件来进行数据复制。
复制的步骤可以分为三步。
如果你现在有两台MySQL,一台版本是03年的MySQL5.0,另一台是18年的MySQL8.0.11。新版本可以作为老版本的从服务器,但反过来是不可行的。MySQL的复制具有向后兼容性,老版本可能无法解析新版本的新特性,甚至复制的文件格式都差异太大。
面试官:那Binary Log日志格式知道有哪些?
MySQL提供了三种二进制日志格式用于主从复制。
面试官:知道哪种二进制格式比较好吗?
基于语句的二进制文件,有可能会出现数据不一致的问题。例如某条删除语句SQL要删除10000条数据中的1000条,这条删除语句没有采用order by进行排序。如果主、从服务器存储数据的顺序不一样,就会导致每次执行删除的数据都是不同的。
# 没有排序的删除语句
delete from test where name = 'JavaGetOffer' limit 1000;
# 有排序的删除语句
delete from test where name = 'JavaGetOffer' order by id asc limit 1000;
混合模式的话不确定因素太多,两种复制模式的不断切换可能回导致二进制日志出现不可预测的事件。如果从服务器复制该二进制文件后的数据库状态是混乱无序的,那整个复制的过程就没有意义了。
一般来说选择行的复制会更加稳妥,也更加安全。虽然二进制文件过大会带来带宽压力大和复制较慢的问题,但比起数据安全性来说,显然后者更加重要。
面试官:那MySQL主从模式有什么好处?
大家如果有细看第一个面试官问题
就知道上文已经有答案了,我这里再总结下。
面试官:如果把二进制文件丢给从库,从库是不是复制整个文件?
能设计出MySQL的聪明人肯定不会这么傻。如果二进制文件包含了已存在的数据,就会造成数据重复了。
MySQL从库只会复制它本身缺失的最新数据,利用二进制文件里的全局事务标识符(GTID)就可以找到对应的二进制文件具体位置。
主库的每一次事务提交都会被分配一个唯一的全局事务标识符,这个标识由server_uuid和一个递增的事务编号组成。
MySQL从库是根据本身当前全局事务标识符找到二进制文件对应位置才进行复制而不是复制全部。
分区的一个主要目的是将数据按照一个较粗的粒度分在不同的区域,这样的话就有很多好处。
# 创建表时同时设置分区
CREATE TABLE sales (
order_date DATETIME NOT NULL,
-- Other columns omitted
) ENGINE=InnODB PARTITION BY RANGE(YEAR(order_date)) (
PARTITION P2010 VALUES LESS THAN(2010),
PARTITION P2011 VALUES LESS THAN(2011),
PARTITION P2012 VALUES LESS THAN(2012),
PARTITION pCatchall VALUES LESS THAN MAXVALUE);
MySQL视图本身是一个虚拟表,不存放任何数据,其实就相当于保存了一条Select语句,把这条Select语句封装成视图。
我举个例子吧。在业务开发中,如果不得不改变MySQL表名,而不想改动代码的表名。可以用视图查询新表名的内容,然后把视图命名为旧表名,这样查询视图也能查询出数据。
CREATE VIEW 新表名 AS
SELECT * FROM 旧表名
MySQL高级特性还包括了存储过程、触发器和事件。
例如可以让MySQL执行函数来插入1万条数据
例如可以编写触发器,在插入A表数据时,给日志记录B表插入一条日志
例如可以创建一个事件每隔一段时间调用下我们定义的一个存储过程
MySQL全文索引类似于ElasticSearch的全文索引。
主要是针对文本内容这种格式的数据,MySQL全文索引会对字段进行分词处理,返回匹配相关的文本内容。
创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。