高性能MySQL学习总结一----MySQL常见概念

一、MySQL逻辑架构

 

  第一层的服务不是MySQL独有的,大多数是基于网络的客户端/服务端的工具,如连接处理、授权认证、安全等等。

  第二层就是MySQL的核心功能,包括查询解析、分析、优化、缓存以及所有的内置函数,所有的跨存储引擎的功能都在这一层实现:存储过程、触发器、视图等。

  第三层包含了存储引擎,主要负责MySQL中数据的存储和提取。

1.连接管理与安全

  每个客户端连接都会服务器进程中拥有一个线程,这个连接的查询只会在这个单独的线程中执行,该线程只能轮流在某个CPU核心或者CPU中运行,服务器会缓存线程,所以不需要对每个连接新建或者销毁一个线程(可以复用缓存中的线程)。

  当客户端连接到MySQL时服务器需要对其进行认证,如果认证成功,服务器会继续验证该客户是否有执行某个待定查询的权限。

2.优化与执行

  MySQL会解析查询,并且创建内部数据结构(解析树),然后对其进行各种优化,包括重写查询SQL、决定表的读取顺序,以及选择合适的索引等。

  对于一个SELECT查询语句来说:在解析查询之前,服务器会先检查查询缓存,如果能够在其中找到对应的查询,服务器会直接返回结果,不需要再执行查询解析、优化和执行整个过程。

二、并发控制

1.读写锁

  比如有一张表,多个线程对这张表进行操作,加入刚好有一个线程在对一条数据更改,另一个线程也对其进行读取操作,那么进行读操作的这个线程可能读到的数据是不正确的,怎么解决这个问题呢?这时就用到了并发控制,主要是通过两种锁来控制的:读锁(共享锁)、写锁(排他锁)

  读锁是共享的,或者说是相互不阻塞的,即对个线程读取同一个资源,互不干扰;写锁是排他的,也就是说只要有一个线程对其进行写操作,那么其他的读和写线程将都会被阻塞。只有这样才能保证才能保证在给定的时间内只有一个线程在写操作,并防止其他线程读取正在写入的数据。

2.锁粒度

  最理想的情况是:需要写入哪个对象就锁定哪个对象。尽量只锁定需要修改的部分数据,而不是所有的数据。在任何时候,在给定的资源上,锁定的数据越少,系统的并发程度越高。

  但是还有一个问题,加锁也会消耗资源,锁的各种操作:获得锁、检查锁是否已经解除、释放锁等,都会增加系统的开销,如果花费大量的时间来管理锁,而不是存取数据,那么系统的性能将会受到影响。

  所谓的锁策略,就是在锁的开销和数据的完全性之间寻求平衡。

  表锁是MySQL中最基本的锁策略,并且是开销最小的策略(意味着并发程度低),但是表锁的缺点是在执行插入、删除、更改的操作时会使其他的用户线程阻塞。(注意:读锁之间是互不影响的)。另外写锁比读锁的优先级更高。写锁可以插到读锁中,但是读锁却不能插到写锁中。

  行级锁:可以最大程度的支持并发处理(但是同时也带来了更大的锁开销)最典型的就是InnoDB存储引擎,行级锁只在存储引擎层实现。

三、事务

  最重要的事务终于到啦,事务即ACID(原子性、一致性、隔离性、持久性),在开始讲这四个特性之前我们先举一个最经典的例子:某账户存了1000元,现在用户A要往里面存200元、用户B要往出来取200元。

  原子性:一个事务必须被视为不可分割的最小工作单元,整个事务的所有操作要么全部提交完成,要么全部失败回滚,对于一个事务来说不可能执行其中的一部分。那上面例子来说:A要从账户取200需要执行以下四步操作:

 

1 START TRANSACTION;
2 SELECT  '金额'  FROM  账户表WHERE   user_id = 12212213 UPDATE  SET  '  =  - 200  WHERE 4 COMMIT;

 

  解释:1.开启事务 ,2.查询账户有没有200元 ,3.扣除金额  , 4.提交事务。

  原子性就是指这四步完整执行不可再分。

  一致性:数据库从一个一致性的状态转换为另一个一致性的状态。就上面那个例子:如果在第三步执行完系统崩溃,账户中的金额还是1000元,因为一个事务没有执行完,在最终提交前是不会保存到数据库中的。

  隔离性:通常来讲一个事务在最终提交前,对其他事务是不可见的。就之前例子来说,第三步执行完,在没提交之前B账户来看到的金额仍然是1000元。是不可见的。

  持久性:事务一旦提交其所做的修改就会永远的被保存到数据库中,即使系统崩溃也不会丢失。

  一个实现了事务的数据库相比于没有实现事务的数据库它需要更强的CPU处理能力、更大的内存、更多的磁盘空间。对于有些不需要事务的查询类应用选择一个非事务型的存储引擎可以获得更高的性能。

1.隔离级别

一共有四种隔离级别先简单做个介绍:

A.READ  UNCOMMIT(读未提交)

  在这个隔离级别中,事务的修改,即使没有提交,对其他的事务也是可见的。事务可以读到未提交的数据,这些数据也被称为脏读。

B.READ  COMMIT(读已提交)(不可重复读)

  大多数数据库系统的默认隔离级别都是读已提交,但是MySQL不是,MySQL的默认隔离级别是可重复读。简单说就是一个事务开始时只能 “看见” 已经提交的事务所做的修改,换句话说,一个事务从开始到提交这个过程中所做的所有修改对其他事务是不可见的。这个级别对于两次执行相同情况的查询,可能会得到不同的结果。

C.REPEATABLE  READ(可重复读)

  该级别保证了在同一个事务中多次读取同样的记录结果是一致的,但是它无法解决幻读的问题。

D.SERIALIZABLE(可串行化)

  是最高的隔离级别。它通过强制事务串行化执行,避免了所有问题,他会在读取的每一行记录上面都加锁,所以可能导致大量的超时与锁等待的问题,并发低。

讲几个概念:

1.脏读:A用户把钱取出没有提交,B用户读取到修改了的金额为800,过一会A因为异常事务回滚,B再次读取发现值变为1000,两次不一样,第一次读到的是脏数据。

2.不可以重复读:B读到数据为1000后,A修改数据为800并且提交,B再次读取为800,两次数据不一致。

3.幻读:与不可重复读类似:B读到一个表里有10条记录,A插了一条并提交,B再次读为11条,感觉发生幻觉一样。

不同隔离级别引发的问题:

 2.死锁

多个事务在同一资源上相互占有,并且请求锁定对方占用的资源,从而导致恶性循环的现象。

数据库系统实现了各种死锁检测和死锁超时机制。InnoDB目前处理死锁的方法是:将持有最少行排它锁的事务进行回滚。

3.事务日志

事务日志可以提高事务的效率,使用事务日志时:存储引擎在修改表数据时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中,不用每次将修改的数据本身持久到硬盘。事务日志采用追加的方式,写日志的操作是磁盘上的一小块区域内的顺序I/O.事务日志持久后,内存中被修改的数据将在后台慢慢刷回到磁盘。所以一共需要两次磁盘I/O:一次写日志磁盘I/O,一次刷回磁盘I/O.

4.MySQL中的事务

1.自动提交:MySQL默认采用自动提交的方式。比如每个查询就是一个事务执行完自动提交。

2.非事务型存储引擎如:MyISAM无回滚功能。

四、多版本并发控制MVCC

  可以认为MVCC是行级锁的一个变种,它在很多情况下避免了加锁,MVCC的实现是通过保存数据在某个时间的快照来实现的。

  InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的,这两个列一个保存了行的创建时间,一个保存了行的删除时间,存储的不是真正时间而是系统的版本号。每个新事物开始系统版本号自动递增。事物开始时刻的版本号作为事物的版本号,用来和查询到的每行记录版本号进行比较。

  MVCC只在可重复读和读已提交两个隔离级别下工作,其他两个级别都和MVCC不兼容。因为读未提交总是读取最新的数据行,不符合当前事物版本的数据行。可串行化会对所有行加锁。

  我的理解其实MVCC就跟CAS是一个原理,就是一个比较并交换的过程。

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


在正式开始之前,我们先来看下 MySQL 服务器的配置和版本号信息,如下图所示: “兵马未动粮草先行”,看完了相关的配置之后,我们先来创建一张测试表和一些测试数据。 -- 如果存在 person 表先删除 DROP TABLE IF EXISTS person; -- 创建 person 表,其中
> [合辑地址:MySQL全面瓦解](https://www.cnblogs.com/wzh2010/category/1859594.html "合辑地址:MySQL全面瓦解") # 1 为什么需要数据库备份 - 灾难恢复:当发生数据灾难的时候,需要对损坏的数据进行恢复和
物理服务机的CPU、内存、存储设备、连接数等资源有限,某个时段大量连接同时执行操作,会导致数据库在处理上遇到性能瓶颈。为了解决这个问题,行业先驱门充分发扬了分而治之的思想,对大库表进行分割,
然后实施更好的控制和管理,同时使用多台机器的CPU、内存、存储,提供更好的性能。而分治有两种实现方式:垂直拆
1 回顾 上一节我们详细讲解了如何对数据库进行分区操作,包括了 垂直拆分(Scale Up 纵向扩展)和 水平拆分(Scale Out 横向扩展) ,同时简要整理了水平分区的几种策略,现在来回顾一下。 2 水平分区的5种策略 2.1 Hash(哈希) 这种策略是通过对表的一个或多个列的Ha
navicat查看某个表的所有字段的详细信息 navicat设计表只能一次查看一个字段的备注信息,那怎么才能做到一次性查询表的信息呢?SELECT COLUMN_NAME,COLUMN_COMMENT,COLUMN_TYPE,COLUMN_KEY FROM information_schema.CO
文章浏览阅读4.3k次。转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52768613前言:数据库每天的数据不断增多,自动删除机制总体风险太大,想保留更多历史性的数据供查询,于是从小的hbase换到大的hbase上,势在必行。今天记录下这次数据仓库迁移。看下Agenda:彻底卸载MySQL安装MySQL_linux服务器进行数据迁移
文章浏览阅读488次。恢复步骤概要备份frm、ibd文件如果mysql版本发生变化,安装回原本的mysql版本创建和原本库名一致新库,字符集都要保持一样通过frm获取到原先的表结构,通过的得到的表结构创建一个和原先结构一样的空表。使用“ALTER TABLE DISCARD TABLESPACE;”命令卸载掉表空间将原先的ibd拷贝到mysql的仓库下添加用户权限 “chown . .ibd”,如果是操作和mysql的使用权限一致可以跳过通过“ALTER TABLE IMPORT TABLESPACE;”命令恢_alter table discard tablespace
文章浏览阅读225次。当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化:单表优化除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑、部署、运维的各种复杂度,一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下是没有太大问题的。而事实上很多时候MySQL单表的性能依然有不少优化空间,甚至能正常支撑千万级以上的数据量:字段尽量使用TINYINT、SMALLINT、MEDIUM_INT作为整数类型而非INT,如果非负则加上UNSIGNEDVARCHAR的长度只分配_开发项目 浏览记录表 过大怎么办
文章浏览阅读1.5k次。Mysql创建、删除用户MySql中添加用户,新建数据库,用户授权,删除用户,修改密码(注意每行后边都跟个;表示一个命令语句结束):1.新建用户登录MYSQL:@>mysql -u root -p@>密码创建用户:mysql> insert into mysql.user(Host,User,Password) values("localhost_删除mysql用户组
MySQL是一种开源的关系型数据库管理系统,被广泛应用于各类应用程序的开发中。对于MySQL中的字段,我们需要进行数据类型以及默认值的设置,这对于数据的存储和使用至关重要。其中,有一个非常重要的概念就是MySQL字段默认字符串。 CREATE TABLE `my_...
MySQL是一个流行的开源关系型数据库管理系统,广泛应用于Web应用程序开发、数据存储和管理。在使用MySQL时,正确设置字符集非常重要,以确保数据的正确性和可靠性。 在MySQL中,字符集表示为一系列字符和字母的集合。MySQL支持多种字符集,包括ASCII、UTF...
MySQL存储函数 n以内偶数 MySQL存储函数能够帮助用户简化操作,提高效率,常常被用于计算和处理数据。下面我们就来了解一下如何使用MySQL存储函数计算n以内的偶数。 定义存储函数 首先,我们需要定义一个MySQL存储函数,以计算n以内的偶数。下...
MySQL是一个流行的关系型数据库管理系统,基于客户机-服务器模式,可在各种操作系统上运行。 MySQL支持多种字符集,不同的字符集包括不同的字符,如字母、数字、符号等,并提供不同的排序规则,以满足不同语言环境的需求。 //查看MySQL支持的字符集与校对规...
在MySQL数据库中,我们有时需要对特定的字符串进行截取并进行分组统计。这种操作对于数据分析和报表制作有着重要的应用。下面我们将讲解一些基本的字符串截取和分组统计的方法。 首先,我们可以使用substring函数对字段中的字符串进行截取。假设我们有一张表stude...
MySQL提供了多种字符串的查找函数。下面我们就一一介绍。 1. LIKE函数 SELECT * FROM mytable WHERE mycolumn LIKE 'apple%'; 其中"apple%"表示以apple开头的字符串,%表示任意多个字符...
MySQL 是一种关系型数据库管理系统,广泛应用于各种不同规模和类型的应用程序中。在 MySQL 中,处理字符串数据是很常见的任务。有时候,我们需要在字符串的开头添加一定数量的 0 ,以达到一定的位数。比如,我们可能需要将一个数字转换为 4 位或 5 位的字符串,不足的...
MySQL是一种流行的关系型数据库管理系统,支持多种数据类型。以下是MySQL所支持的数据类型: 1. 数值型数据类型: - TINYINT 保存-128到127范围内的整数 - SMALLINT 保存-32768到32767范围内的整数 - MEDIU...
MySQL中存储Emoji表情字段类型 在现代互联网生态中,表情符号已经成为人们展示情感和思想的重要方式之一,因此将表情符号存储到数据库中是一个经常出现的问题。MySQL作为最流行的开源关系型数据库管理系统之一,也需要能够存储和管理这些表情符号的字段类型。 UT...
MySQL是一种关系型数据库管理系统。在MySQL数据库中,有多种不同的数据类型。而其中,最常见的数据类型之一就是字符串类型。在MySQL中,字符串类型的数据通常会被存储为TEXT或VARCHAR类型。 首先,让我们来看一下VARCHAR类型。VARCHAR是My...
MySQL字符串取整知识详解 MySQL是一种开源的关系型数据库管理系统,广泛应用于各个领域。在使用MySQL过程当中,我们经常需要对数据进行取整操作。本文将介绍如何使用MySQL字符串取整来处理数据取整问题。 什么是MySQL字符串取整? MySQL...