深挖MySQL —— MySQL初探

        隔了好几年没有写博客了,突然又想动笔写点什么。从事开发这几年从没停下过自学的脚步,但所谓一入软件深似海,随着看的东西越多越是不敢下笔。总是觉得自己的理解差了点什么,就像每次翻过同一本书,每次都能看到不少之前理解的偏差,总是怕写的东西贻笑大方。不过转念想,好歹努力过,学习过,总还是留下点痕迹,如果有幸有一二位读者看到我的文章,能对自己有一些帮助,那也还算有些意义了。言而总之,话不多说,来分享下这些年对MySQL的学习和理解吧。

一、MySQL的历史背景

        相信大部分人对此也没什么兴趣,不想浪费时间直接跳过本段也无伤大雅,不过是知道了如今完善的功能也非一就而成,积少成多,聚沙成塔。对于MySQL的历史背景我也了解不多,无非就是从1995年第一个版本发布后慢慢的发展至今,不过有几个我觉得是里程碑式的节点可以了解一下:

        1、innodb问世:InnoDB引擎由InnobaseOy公司开发,后续为oracle公司收购,innodb问世后,MySQL总算对事务有了较好的支持。为后续与其它关系型数据库竞争做好铺垫。此时的innodb只支持ACID、行锁设计、MVCC多版本并发控制(对于MVCC、存储引擎和MySQL的关系,后续会展开介绍。ACID不知道是什么?好好复习下事务的四大特性去)

        2、MySQL5.1版本发布:2001年开始,Innobase公司开始与MySQL AB公司进行合作并开源InnoDB存储引擎的代码,oracle于2008年收购了Innobase,同年发布了InnoDB Plugin,或者称为innodb 1.0.x,在原有基础上,增加了compress和dynamic页格式(旧版页格式只有compact和redundant。mysql的数据、索引等以页的形式存储在磁盘和缓存在内存里面,此事说来话长,后续再介绍也无妨)

        3、MySQL5.5版本发布:此时innodb升级到了1.1.x版本,增加了Linux AIO和多段回滚

        4、MySQL5.5.8版本的发布:从这个版本开始,MySQL将之前的myisam默认存储引擎改成了默认使用oracle公司收购来的、我们最熟悉的innodb存储引擎,从此,MySQL的OLTP应用时代来临(OLTP on-line transaction processing,字面意思,偏重事务,myisam是OLAP应用,On-Line Analytical Processing,没有事务,偏向查询,统计,分析)

        5、MySQL5.6版本发布:5.6之后的版本也是我们现在比较熟悉的数据库版本了,此时的innodb升级到了1.2.x,增加全文索引和在线索引添加(值得一提的是,以前我一直以为实现在线索引添加是很简单的小事)

二、MySQL数据库和存储引擎

        这里着重提一下我也一度混淆的几个概念:

        数据库:数据库指的是一系列文件的集合:在MySQL里的frm文件、ibdata文件、ibd文件等

        数据库实例:由后台线程以及一个共享内存区组成,在系统上的表现就是一个进程,我们(使用者)通过数据库实例这个进程来操作数据库文件

        平时我们常常将数据库和实例混淆,其实也没什么问题,反正双方能正确的交流表达就没有问题。至于“存储引擎”这个概念,为MySQL独有(实际上我也不知道有没有别的数据库有这东西,反正oracle和sql server没有)。存储引擎的优势就是MySQL可以通过不同的存储引擎,建立不同的存储引擎表,而不同的存储引擎有着各自的特性。在此,让我们打一下比方(比方同学,无意冒犯):

        innodb:MySQL的OLTP应用中,应用的最广泛的存储引擎,支持行锁、外键、独立的表空间ibd文件、MVCC、sql标准的4个事务隔离级别等(最早是第三方引擎,后被收购;这说明什么?说明这种开源的东西你也有机会写一个,然后被收购,然后大名鼎鼎)

        myisam:MySQL5.5.8前的默认存储引擎,不支持事务,支持全文索引,且缓冲池只缓存索引文件,不缓存数据文件

        maria:可以看作myisam的升级版,对比myisam多了行锁、MVCC、支持缓存数据文件等

        ndb、memory:把这两个放在一起是因为这俩的数据都是放在内存的,速度非常快,但是不安全,没怎么用过不多介绍,想具体深入了解的自行解决了

       除了上述的各个存储引擎外,还有很多其它的存储引擎,它门各有特色,在自己的领域上发挥着各自的优势,不过大部分使用者比较熟悉的应该还是innodb(相信大部分读者也基本上只会用上innodb),其它感兴趣的读者请自行了解了。下面,我画了一张图,大概展示MySQL的结构:

        可以看到,MySQL是一个经典的插件式开发案例,它提供了一系列标准和服务支持,底层的物理结构由存储引擎实现,存储引擎开发者可自由的按自己意愿开发(你还在等什么呢,大牛)。

三、MySQL数据库的相关文件

        这里介绍一下比较常看到的文件,不太常看到的反正你也看不见。

       1、参数文件

        打开你的命令行,linux下输入mysql --help | grep my.,或者在windows下输入mysql --help | findstr my.,你大概就会看到好几个my.cnf和my.ini文件(cnf和ini都会有,ini是windows用的,cnf是linux用的),这就是MySQL的参数文件了,文件里出现相同的参数的时候,你的命令行输出的文件中,越往后优先级越高(就是说以后面的那个文件为准)。MySQL和oracle在参数文件上有一个区别,就是这些文件全删了也是不会影响MySQL实例的启动,这是因为MySQL编译的时候偷偷的把默认参数编译进去了。

        对于MySQL的参数,在实例中可以使用命令show variables like 'xxxx'来查看。MySQL的参数作用域有三个级别:静态(永久)、动态(全局、会话)。所谓静态(永久),就是配置文件上的参数,此类参数需要重启生效。动态参数可以使用set [global|session] xxx = yyy来动态修改,顾名思义,全局global就是对所有会话都生效,session只对本会话生效。有的参数只能在会话中修改,如autocommit,有的修改了会在全局生效,如binlog_cache_size。参数繁多,等遇上了再了解不迟。

        2、套接字文件

        顾名思义,就是在使用套接字连接的时候用到的文件,一般在/tmp/mysql.sock

        3、pid文件

        一般在MySQL实例启动的时候,会将进程ID写入pid文件,一般在/数据库目录/主机名.pid

        4、frm表结构定义文件

        由于插件式存储引擎的关系,MySQL的数据存储是根据表进行的,不同的表使用的存储引擎可以不同。但是无论使用哪种存储引擎都是由frm文件来记录表的结构定义,同时,MySQL的视图也是使用frm文件记录

        5、innodb引擎表空间文件

        innodb的表空间划分为公告表空间“ibdata”和独立表空间“表名.ibd”(独立表空间有一个开关参数:innodb_file_per_table),公告表空间默认文件时ibdata1,可以通过innodb_data_file_path参数拆分成多个文件组成。独立表空间里面只存放表的数据、索引、插入缓冲位图等信息。

        6、日志文件

        之所以把日志文件放在大轴位(最后),一个是因为这个比较重要,一个是因为这个比较复杂,MySQL的日志文件有部分有独立的文件存放;还有一部分比如回滚日志undo log,是记录在公共表空间的;还有记录在数据表里面,比如慢查询日志记录在mysql.slow_log。下面简单列一下MySQL的各类日志:

        1> 错误日志,可以通过参数log_error查看错误日志的存放位置,当数据库不能正常启动/重启的时候,第一个必须查找的文件就是错误日志。并且,还能通过错误日志里的一些警告发现数据库优化的提示

        2> 慢查询日志,默认情况下数据库是不启动慢查询日志记录的,需要将开关参数log_slow_queries设置成ON打开。参数long_query_time可以设置超过几秒的查询记录为慢查询,long_queries_not_using_indexes参数设置将没用到索引的查询也记录在慢查询日志

        3> 查询日志,据说记录在主机名.log文件下,但是我并没有找到。不过没关系,MySQL5.1版本后可以设置general_log参数让他记录在mysql.general_log表中

        4> 二进制日志bin log,二进制日志记录的是所有对MySQL执行的更改操作(当然不包过select和show),记录时机为事务提交后写入,二进制日志是不会删除的,所以可以通过它让数据库恢复到任意时间点的状态,此操作称为point-in-time。并且可以将重做日志用于复制操作:如搭建主从集群,可以通过二进制日志来实现主从数据同步。最后还能通过对二进制日志的审计来判断是否有对数据库的注入攻击

        5> 上面列举的都是MySQL的日志文件,下面说的两个是innodb独有的日志文件。重做日志redo log,默认记录在名为ib_logfile0和ib_logfile1文件组中。记录方式为每秒写入、循环写入:1写满了写2,2写满了写1,这里可以看出和二进制日志的区别,由于覆盖操作,这里是没有记录所有更改的,无法作point-in-time操作。可以通过innodb_mirrored_log_groups参数设置文件组的镜像,提高可用性。重做日志是保证事务原子性A和持久性I的重要保障(怎么保障后面篇章再介绍了,现在有这么一个概念就行),所以不能设置的太小,不然一个事务里需要来回的切换重做日志文件;重做日志也是数据库宕机后恢复事务的保障,所以此文件不能设置的太大,不然恢复的时候会需要很长的时间  

        6> 回滚日志undo log,回滚日志是保证事务一致性C的重要保障,undo log记录在表空间的undo段,undo段位于公共表空间。回滚的原理是作与之前相反的操作,比如对于delete,实际上它的删除是逻辑删除,数据保留在数据库中,回滚时innodb会执行相应的insert操作,重要的时undo log的产生会伴随redo日志的产生,这是对undo log持久性的保护。undo log另一个重要作用是对MVCC Multi-Version Concurrency Control多版本并发控制的实现

        由于篇幅问题,相信读者对重做日志和回滚日志的实现还是保有许多疑问,后续再单独开篇分享吧,这里有一个概念就差不多不影响后续阅读。

四、安装和连接

        下载地址:https://dev.mysql.com/downloads/mysql/,下载和自己操作系统匹配的版本,安装过程相信优秀的你知道该怎么点击下一步。

         MySQL的连接方式有三种,最常用的是TCP/IP连接,一般像heidsql、navicat客户端也是用此协议连接,在linux下命令为:mysql -h 192.168.0.xxx -u root -p。另外两种连接方式分别为命名管道连接和uninx套接字连接,由于不太常用这里不再追述,想秀操作的你为何不问问神奇的海螺如何操作呢。

如有错误,敬请斧正;欢迎转载,但请务必注明出处;最后,在此向神奇的海螺保证,绝不太监!!!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值