学习

06B+树索引

学习《MySQL是怎样运行的》,感谢作者!

概述 #

数据页由7个组成部分,各个数据页可以组成一个双向链表,每个数据页中的记录会按照主键值从小到大的顺序组成一个单向链表。每个数据页都会为它里面的记录生成一个页目录,在通过主键查找某条记录的时候可以在页目录中使用二分法快速定位到对应的槽,然后再遍历该槽对应分组中的记录即可快速找到指定的记录。页和记录的关系

页a,页b 可以不在物理结构上相连,只要通过双向链表相关联即可

ly-20241212142156258

没有索引时进行查找 #

假设我们要搜索某个列等于某个常数的情况:
SELECT [查询列表] FROM 表名 WHERE 列名 = xxx

在一个页中查找 #

假设记录极少,所有记录可以存放到一个页中

  • 主键位搜索条件:页目录中使用二分法快速定位到对应的,然后在遍历槽对应分组中的记录,即可快速找到指定记录
  • 其他列作为搜索条件:对于非主键,数据页没有为非主键列建立所谓的页目录,所以无法通过二分法快速定位相应的槽。只能从Infimum依次遍历单向链表中的每条记录,然后对比,效率极低

在很多页中查找 #

两个步骤:

  • 定位到记录所在的页
  • 所在页内查找相应的记录

没有索引情况下,不能快速定位到所在页,只能从第一页沿着双向链表一直往下找,而如果是主键,每一页则可以在页目录二分查找。
不过由于要遍历所有页,所以超级耗时

索引 #

#例子
mysql> CREATE TABLE index_demo(
      c1 INT,
      c2 INT,
      c3 CHAR(1),
      PRIMARY KEY(c1)
      ) ROW_FORMAT=COMPACT;

完整的行格式

ly-20241212142156429

简化的行格式
ly-20241212142156467

  • record_type:记录头信息的一项属性,表示记录的类型。0:普通记录,2:Infimum记录,3:Supremum记录,1还没用过等会再说
  • next_record:记录头信息的一项属性,表示从当前记录的真实数据下一条记录真实数据的距离
  • 各个列的值:这里只展示在index_demo表中的3个列,分别是c1、c2、c3
  • 其他信息:包括隐藏列记录的额外信息

改为竖着查看:
ly-20241212142156521

上面图6-4的箭头其实有一点点出入,应该是指向z真实数据第1列那个位置,如下 ly-20241212142156561

...

05InnoDB数据页结构

学习《MySQL是怎样运行的》,感谢作者!

不同类型的页简介 #

页是InnoDB管理存储空间的基本单位,1个页的大小一般是16KB

InnoDB为了不同目的设计多种不同类型的页,包括存放表空间头部信息 的页、存放Change Buffer 信息的页、存放INODE信息的页、存放undo 日志信息的页

这里说的是存放表中记录的那种类型的页,这种存放记录的页称为索引页(INDEX页)

暂时称之为数据页

数据页结构快览 #

1个页有16KB,这部分存储空间被划分为了多个部分(7部分),不同部分有不同的功能
ly-20241212142155323

名称中文名占用空间大小
File Header文件头部38 字节页的一些通用信息
Page Header页面头部56 字节数据页专有的一些信息
Infimum + Supremum页面中的最小记录和最大记录26 字节两个虚拟的记录
User Records用户记录不确定用户存储的记录内容
Free Space空闲空间不确定页中尚未使用的空间
Page Directory页目录不确定某些记录的相对位置
File Trailer文件尾部8 字节校验页是否完整

记录在页中的存储 #

每插入一条记录,从Free Space申请一个记录大小的空间,并将这个空间划分到UserRecords部分。当FreeSpace部分的空间全部被UserRecords部分替代掉后,意味着该页用完。如果再插入,就需要申请新的页

ly-20241212142155485

记录头信息的秘密 #

mysql> CREATE TABLE page_demo(
      c1 INT,
      c2 INT,
      c3 VARCHAR(10000),
      PRIMARY KEY(c1)
      ) CHARSET=ascii ROW_FORMAT=COMPACT;
Query OK, 0 rows affected (0.03 sec)

ly-20241212142155528

...

04InnoDB记录存储结构

学习《MySQL是怎样运行的》,感谢作者!

问题 #

表数据存在哪,以什么格式存放,MySQL以什么方式来访问
存储引擎:对表中数据进行存储写入
InnoDB是MySQL默认的存储引擎,这章主要讲InnoDB存储引擎的记录存储结构

InnoDB页简介 #

注意,是简介
InnoDB:将表中的数据存储到磁盘上
真正处理数据的过程:内存中。所以需要把磁盘中数据加载到内存中,如果是写入修改请求,还需要把内存中的内容刷新到磁盘
获取记录:不是一条条从磁盘读,InnoDB将数据划分为若干个页,以作为磁盘内存之间交互的基本单位。页大小-> 一般是16KB
一般情况:一次最少从磁盘读取16KB的内容到内存中,一次最少把内存中的16KB内容刷新到磁盘

mysql>  SHOW VARIABLES LIKE 'innodb_page_size';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
1 row in set (0.00 sec)

只能在第一次初始化MySQL数据目录时指定,之后再也不能更改(通过mysqld –initialize初始化数据目录[旧版本])

InnoDB行格式 #

以记录为单位向表中插入数据,而这些记录在磁盘上的存放形式也被称为行格式或者记录格式
目前有4中不同类型的行格式:COMPACT、REDUNDANT、DYNAMIC和COMPRESSED

compact [kəmˈpækt]契约
redundant[rɪˈdʌndənt] 冗余的
dynamic[daɪˈnæmɪk]动态的
compressed [kəmˈprest] 压缩的

指定行格式的语法 #

CREATE TABLE 表名(列的信息) ROW_FORMAT=行格式名称
ALTER TABLE 表名 ROW_FORMATE=行格式名称
如下,在数据库xiaohaizi下创建一个表

CREATE TABLE record_format_demo(
      c1 VARCHAR(10),
      c2 VARCHAR(10) NOT NULL,
      c3 CHAR(10),
      c4 VARCHAR(10)
      ) CHARSET=ascii ROW_FORMAT=COMPACT;  
#回顾:ascii每个字符1字节即可表示,且只有空格标点数字字母不可见字符
#插入两条数据
INSERT INTO record_format_demo(c1,c2,c3,c4) VALUES('aaaa','bbb','cc','d'),('eeee','fff',NULL,NULL);

查询

...

03字符集和比较规则

学习《MySQL是怎样运行的》,感谢作者!

字符集 #

把哪些字符映射成二进制数据:字符范围
怎么映射:字符->二进制数据,编码;二进制->字符,解码
字符集:某个字符范围的编码规则
同一种字符集可以有多种比较规则

重要的字符集 #

ASCAII字符集:128个,包括空格标点数字大小写及不可见字符,使用一个字节编码
ISO 8859-1字符集:256个,ASCAII基础扩充128个西欧常用字符(包括德法),使用1个字节,别名Latin1
GB2312字符集:收录部分汉字,兼容ASCAII字符集,如果字符在ASCAII字符集中则采用1字节,否则两字节。即变长编码方式

区分某个字节,代表一个单独字符,还是某个字符的一部分
比如0xB0AE75,由于是16进制,所有两个代表1个字节。所以这里有三个字节,其中最后那个字节为7*16+5=117 < 127 所以代表一个单独字符。而AE=10 * 16 +15=175 >127 ,所以是某个字符的一部分

GBK字符集:对GB2312字符集扩充,编码方式兼容GB2312
UTF-8字符集:几乎收录所有字符,且不断扩充,兼容ASCAII字符集。变长:采用14字节
L->0x4C 1字节,啊->0xE5958A,两字节
UTF-8是Unicode字符集的一种编码方案,Unicode字符集有三种方案:UTF-8(1
4字节编码一个字符),UTF-16(2或4字节编码一个字符),UTF-32(4字节编码一个字符)

对于**“我”**,ASCLL中没有,UTF-8中采用3字节编码,GB22312采用2字节编码

MySQL中支持的字符集和比较规则 #

MySQL中,区分utf8mb3和utf8mb4,前者只是用13字节表示字符;后者使用14字节表示字符。MySQL中,utf8代表utf8mb3。

#查看当前MySQL支持的字符集(注意,是字符集,名称都是小写)
#Default collation 默认比较规则
mysql> SHOW CHARSET;
+----------+---------------------------------+---------------------+--------+
| Charset  | Description                     | Default collation   | Maxlen |
+----------+---------------------------------+---------------------+--------+
| big5     | Big5 Traditional Chinese        | big5_chinese_ci     |      2 |
| dec8     | DEC West European               | dec8_swedish_ci     |      1 |
| cp850    | DOS West European               | cp850_general_ci    |      1 |
| hp8      | HP West European                | hp8_english_ci      |      1 |
| koi8r    | KOI8-R Relcom Russian           | koi8r_general_ci    |      1 |
| latin1   | cp1252 West European            | latin1_swedish_ci   |      1 |  <---
| latin2   | ISO 8859-2 Central European     | latin2_general_ci   |      1 |  <---
| swe7     | 7bit Swedish                    | swe7_swedish_ci     |      1 |
| ascii    | US ASCII                        | ascii_general_ci    |      1 |  <---
| ujis     | EUC-JP Japanese                 | ujis_japanese_ci    |      3 |
| sjis     | Shift-JIS Japanese              | sjis_japanese_ci    |      2 |
| hebrew   | ISO 8859-8 Hebrew               | hebrew_general_ci   |      1 |
| tis620   | TIS620 Thai                     | tis620_thai_ci      |      1 |
| euckr    | EUC-KR Korean                   | euckr_korean_ci     |      2 |
| koi8u    | KOI8-U Ukrainian                | koi8u_general_ci    |      1 |
| gb2312   | GB2312 Simplified Chinese       | gb2312_chinese_ci   |      2 |  <---
| greek    | ISO 8859-7 Greek                | greek_general_ci    |      1 |
| cp1250   | Windows Central European        | cp1250_general_ci   |      1 |
| gbk      | GBK Simplified Chinese          | gbk_chinese_ci      |      2 |  <---
| latin5   | ISO 8859-9 Turkish              | latin5_turkish_ci   |      1 |
| armscii8 | ARMSCII-8 Armenian              | armscii8_general_ci |      1 |
| utf8     | UTF-8 Unicode                   | utf8_general_ci     |      3 |  <---
| ucs2     | UCS-2 Unicode                   | ucs2_general_ci     |      2 |
| cp866    | DOS Russian                     | cp866_general_ci    |      1 |
| keybcs2  | DOS Kamenicky Czech-Slovak      | keybcs2_general_ci  |      1 |
| macce    | Mac Central European            | macce_general_ci    |      1 |
| macroman | Mac West European               | macroman_general_ci |      1 |
| cp852    | DOS Central European            | cp852_general_ci    |      1 |
| latin7   | ISO 8859-13 Baltic              | latin7_general_ci   |      1 |  
| utf8mb4  | UTF-8 Unicode                   | utf8mb4_general_ci  |      4 |  <---
| cp1251   | Windows Cyrillic                | cp1251_general_ci   |      1 |
| utf16    | UTF-16 Unicode                  | utf16_general_ci    |      4 |  <---
| utf16le  | UTF-16LE Unicode                | utf16le_general_ci  |      4 |
| cp1256   | Windows Arabic                  | cp1256_general_ci   |      1 |
| cp1257   | Windows Baltic                  | cp1257_general_ci   |      1 |
| utf32    | UTF-32 Unicode                  | utf32_general_ci    |      4 |  <---
| binary   | Binary pseudo charset           | binary              |      1 |
| geostd8  | GEOSTD8 Georgian                | geostd8_general_ci  |      1 |
| cp932    | SJIS for Windows Japanese       | cp932_japanese_ci   |      2 |
| eucjpms  | UJIS for Windows Japanese       | eucjpms_japanese_ci |      3 |
| gb18030  | China National Standard GB18030 | gb18030_chinese_ci  |      4 |
+----------+---------------------------------+---------------------+--------+
41 rows in set (0.00 sec)

字符集的比较规则(这里先看utf8的)

...

02启动选项和系统变量

学习《MySQL是怎样运行的》,感谢作者!

启动选项和配置文件 #

在程序启动时指定的设置项,也称之为启动选项startup option(可以在命令行中/配置文件中 指定)
由于在centos7中使用systemctl start mysqld启动mysql,所以好像没法用命令行指定启动选项了

程序(可能有些程序新版本已经没有了)的对应类别和能读取的组:
ly-20241212142154302

这里讲配置文件的方式设置启动选项:

#添加配置
vim /etc/my.cnf
[server]
skip-networking #禁止tcp网络连接
default-storage-engine=MyISAM #建表默认使用M有ISAM存储引擎


#效果
▶ mysql -h127.0.0.1 -uroot -p
Enter password: 
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (111)

#去除tcp网络连接限制后新建一个表
▶ mysql -h127.0.0.1 -uroot -p #可以连接上
mysql> create table default_storage_engine_demo(i int);
Query OK, 0 rows affected (0.01 sec)
mysql> show create table default_storage_engine_demo;
+-----------------------------+----------------------------------------------------------------------------------------------------------------+
| Table                       | Create Table                                                                                                   |
+-----------------------------+----------------------------------------------------------------------------------------------------------------+
| default_storage_engine_demo | CREATE TABLE `default_storage_engine_demo` (
  `i` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |

如果多个配置文件都配置了某个选项,如/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf都配置了,则以最后一个配置的为主
如果同一个配置文件,比如[server]组和[mysqld]组都出现了default-storage-engine配置,则以后出现的组中的配置为准
如果一个启动选项既在命令行中出现,又在配置文件中配置,则以命令行中的为准

...

01初识MySQL

学习《MySQL是怎样运行的》,感谢作者!

原文 #

下载与安装 #

环境Centos7

添加MySQL5.7仓库

sudo rpm -ivh https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm

解决证书问题

rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

查看是否添加成功

sudo yum repolist all | grep mysql | grep 启用   
mysql-connectors-community/x86_64   MySQL Connectors Community      启用:    213
mysql-tools-community/x86_64        MySQL Tools Community           启用:     96
mysql57-community/x86_64            MySQL 5.7 Community Server      启用:    642

MySQL安装

sudo yum -y install mysql-community-server

运行与密码修改 #

Centos7中安装目录查看,在/usr/bin中,与Max有所不同

whereis mysql
mysql: /usr/bin/mysql /usr/lib64/mysql /usr/share/mysql /usr/share/man/man1/mysql.1.gz
ls /usr/bin |grep mysql
mysql
mysqladmin
mysqlbinlog
mysqlcheck
mysql_config_editor
mysqld_pre_systemd
mysqldump
mysqldumpslow
mysqlimport
mysql_install_db
mysql_plugin
mysqlpump
mysql_secure_installation
mysqlshow
mysqlslap
mysql_ssl_rsa_setup
mysql_tzinfo_to_sql
mysql_upgrade

添加mysqld目录到环境变量中(这里可省略,因为mysqld默认在/usr/bin中了

...

redis集群搭建

转载自https://www.cnblogs.com/Yunya-Cnblogs/p/14608937.html(添加小部分笔记)感谢作者!

部分参考自 https://www.cnblogs.com/ysocean/p/12328088.html

基本准备 #

ly-20241212142159186.png

架构 #

采用Centos7,Redis版本为6.2,架构如下:

ly-20241212142159238

hosts修改 #

vim /etc/hosts
#添加
192.168.1.101 node1
192.168.1.102 node2
192.168.1.103 node3

集群准备 #

对每个节点 #

  1. 下载redis并解压到 /usr/local/redis-cluster中

    cd /usr/local
    mkdir redis-cluster
    tar -zxvf redis* -C /usr/local/redis*
    
  2. 进入redis根目录

    make
    make install
    
  3. 安装完毕

  4. hosts修改

    vim /etc/hosts
    #添加
    192.168.1.101 node1
    192.168.1.102 node2
    192.168.1.103 node3
    

配置文件修改(6个节点中的每一个) #

创建多级目录

mkdir -p /usr/local/redis_cluster/redis_63{79,80}/{conf,pid,logs}

ly-20241212142159275

编写配置文件

...

科目

科目 #

  • 1022/9:00-11:30

    • 00024 普通逻辑 2010
    • 02197 概率论与数理统计(二)2018
    • 02318 计算机组成原理 2016
    • 02324 离散数学 2014
    • 02331 数据结构 2012
    • 03709 马克思主义基本原理概论 2018
    • 04747 Java语言程序设计(一) 2019
  • 1022/14:30-17:00

    • 00023 高等数学(工本) 2019
    • 00342 高级语言程序设计(一)2017
    • 02326 操作系统 2017
    • 04730 电子技术基础(三) 2006
    • 04735 数据库系统原理 2018
  • 1023/09:00-11:30

    • 02325 计算机系统结构 2012
    • 03708 中国近现代史纲要 2018
    • 04737 C++程序设计 2019
  • 1023/14:30-17:00

    • 0015 英语(二)2012
    • 02333 软件工程 2011
    • 04741 计算机网络原理 2018

基本操作

yum源替换成阿里云 #

yum install -y wget
## 备份
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
## 下载
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
## 重建缓存
yum clean all
yum makecache

Java环境搭建 #

yum search java | grep jdk
yum install -y java-1.8.0-openjdk-devel.x86_64
# java -version 正常
# javac -version 正常

解压相关 #

-zxvf

tar -zxvf redis* -C /usr/local/redis*
# z :表示 tar 包是被 gzip 压缩过的 (后缀是.tar.gz),所以解压时需要用 gunzip 解压 (.tar不需要)
# x :表示 从 tar 包中把文件提取出来
# v :表示 显示打包过程详细信息
# f :指定被处理的文件是什么
# 适用于参数分开使用的情况,连续无分隔参数不应该再使用(所以上面的命令不标准),
# 应该是 tar zxvf redis* -C /usr/local/redis*

主题修改 #

oh my zsh

...

vmware上linux主机的安装和克隆

安装 #

虚拟机向导 #

  1. 典型—稍后安装–linux–RedhatEnterpriseLinux7 64
  2. 虚拟机名称rheCentos700
  3. 接下来都默认即可(20G硬盘,2G内存,网络适配器(桥接模式))

安装界面 #

  1. 日期–亚洲上海,键盘–汉语,语言支持–简体中文(中国)

  2. 软件安装
    最小安装—> 兼容性程序库+开发工具

  3. 其他存储选项–配置分区

    1. /boot 1G 标准分区,文件系统ext4
    2. swap 2G 标准分区 ,文件系统swap
    3. / 17G 标准分区,文件系统ext4
  4. 网络和主机名
    打开网络+设置主机名(rheCentos700)

  5. 完成—过程中配置密码 默认用户root+其他用户ly

安装完成后修改ip及网关 #

Centos #

  1. vi /etc/sysconfig/network-scripts/ifcfg-ens**

  2. 修改部分键值对

    BOOTPROTO="static"
    IPADDR=192.168.1.100
    NETMASK=255.255.255.0
    GATEWAY=192.168.1.1
    DNS1=223.5.5.5
    DNS2=223.6.6.6
    
  3. systemctl restart network

Debian #

  1. 查看当前网卡

    ip link
    #1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    #    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    #2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    #    link/ether 00:0c:29:ed:95:f5 brd ff:ff:ff:ff:ff:ff
    #    altname enp2s1
    

    得知网卡名为ens33

    ...