主要内容:
PXC概述、部署PXC(自动故障恢复测试)、存储引擎、读锁/写锁、表锁/行锁、常用的存储引擎介绍
一、PXC概述
PXC(Percona XtraDB Cluster,简称PXC集群),是基于Galera的MySQL高可用集群解决方案,提供了多主复制、自动故障转移和数据一致性等特性。Galera Cluster是Codership公司开发的一套免费开源的高可用方案(MySQL发行版),PXC集群主要由两部分组成:Percona Server with XtraDB 和 Write Set Replication patches(使用了Galera library,一个通用的用于事务型应用的同步、多主复制插件);可以实现多个节点间的数据同步复制以及读写,并且可保障数据库的服务高可用及数据一致性;PXC与mariadb的集群maridb-cluster原理是一样的。
1、PXC主要特性
1)多主复制:
- PXC支持多主复制,这意味着每个节点都可以同时读写,没有单点故障。
- 所有节点都是对等的,任何节点都可以接受写操作。
2)数据一致性:
- PXC使用Galera Cluster的同步复制技术,确保所有节点上的数据一致性。
- 事务在所有节点上同时提交,避免了数据不一致的问题。
3)自动故障转移:
- 当某个节点发生故障时,其他节点会自动接管,确保服务的连续性。
- 无需手动干预,系统会自动检测并处理故障。
4)高可用性:
- PXC通过多节点部署和自动故障转移,提供了高可用性。
- 即使某个节点发生故障,集群仍然可以正常运行。
5)扩展性:
- PXC支持水平扩展,可以通过增加节点来提高集群的处理能力。
- 每个节点都可以处理读写请求,提高了系统的整体性能。
6)低延迟复制:
- PXC的复制是同步的,确保了低延迟的数据复制。
- 数据在所有节点上几乎同时更新,避免了数据延迟的问题。
2、PXC架构
基于Galera Cluster,主要由以下组件组成:
3、端口介绍
① 3306:数据库对外服务的端口号
② 4444:SST端口(State Snapshot Transfer)
③ 4567:集群通信端口
④ 4568:IST端口(Incremental State Transfer)
4、名词介绍
SST(State Snapshot Transfer):
- 全量同步:当一个新的节点加入集群时,它需要从现有节点获取完整的数据副本。SST通过4444端口进行全量数据的传输。
IST(Incremental State Transfer):
- 增量同步:相对于SST来说,IST只传输自上次同步以来的增量数据。当一个节点加入集群时,如果已经有部分数据,可以通过IST端口获取增量数据,而不是全量数据。
WS(write set):
- 写数据集:在PXC中,每个写操作(事务)都会生成一个写数据集(write set),这个写数据集包含了所有需要更新的数据和元数据。写数据集通过4567端口在节点之间进行复制,确保数据一致性。
部署PXC示例:
网络实验拓扑:
- 服务器角色:mysql1、mysql2、mysql3(三台相互独立的mysql服务器)
- Mysql1:IP为192.168.2.11、安装Percona-XtraDB-Cluster
- Mysql2:IP为192.168.2.12、安装Percona-XtraDB-Cluster
- Mysql3:IP为192.168.2.13、安装Percona-XtraDB-Cluster
步骤1:初始化环境准备(主机名解析、安装软件包)
① 配置服务器的名称解析
[root@mysql1 ~]# for i in {1..3}
> do
> echo -e "192.168.2.1$i\tmysql$i" >> /etc/hosts
> done
[root@mysql1 ~]# cat /etc/hosts
192.168.2.11 mysql1
192.168.2.12 mysql2
192.168.2.13 mysql3
[root@mysql2 ~]# for i in {1..3}
> do
> echo -e "192.168.2.1$i\tmysql$i" >> /etc/hosts
> done
[root@mysql1 ~]# cat /etc/hosts
192.168.2.11 mysql1
192.168.2.12 mysql2
192.168.2.13 mysql3
[root@mysql3 ~]# for i in {1..3}
> do
> echo -e "192.168.2.1$i\tmysql$i" >> /etc/hosts
> done
[root@mysql1 ~]# cat /etc/hosts
192.168.2.11 mysql1
192.168.2.12 mysql2
192.168.2.13 mysql3
② 准备yum源(参考:/linux-soft/4/pxc/Percona-XtraDB-Cluster-5.7.25-31.35-r463-el7-x86_64-bundle.tar)
[root@localhost ~]# cd pxc/
[root@ localhost pxc]# tar -xf Percona-XtraDB-Cluster-5.7.25-31.35-r463-el7-x86_64-bundle.tar
[root@ localhost pxc]# ls
[root@ localhost pxc]# cp *.rpm /var/www/html/mysql/ //复制解压的RPM包到/var/www/html/mysql/
[root@ localhost pxc]# cd /var/www/html/mysql/
[root@ localhost mysql]# createrepo -v .
[root@localhost ~]# scp /etc/yum.repos.d/mysql.repo root@192.168.2.11:/etc/yum.repos.d/
[root@localhost ~]# scp /etc/yum.repos.d/mysql.repo root@192.168.2.12:/etc/yum.repos.d/
[root@localhost ~]# scp /etc/yum.repos.d/mysql.repo root@192.168.2.13:/etc/yum.repos.d/
③ 安装软件包(qpress.x86_64、Percona-XtraDB-Cluster-*)
[root@mysql1 ~]# yum clean all
[root@mysql1 ~]# yum -y install qpress.x86_64 Percona-XtraDB-Cluster-*
[root@mysql1 ~]# id mysql
uid=997(mysql) gid=995(mysql) 组=995(mysql)
[root@mysql2 ~]# yum clean all
[root@mysql2 ~]# yum -y install qpress.x86_64 Percona-XtraDB-Cluster-*
[root@mysql3 ~]# yum clean all
[root@mysql3 ~]# yum -y install qpress.x86_64 Percona-XtraDB-Cluster-*
步骤2:配置PXC服务(mysqld.cnf、mysqld_safe.cnf、wsrep.cnf)
[root@mysql1 ~]# ls /etc/percona-xtradb-cluster.conf.d/
mysqld.cnf mysqld_safe.cnf wsrep.cnf
① 分别修改3台服务器的mysqld.cnf配置文件
[root@mysql1 ~]# rm -rf /var/lib/mysql/* //建议清空原有MySQL数据目录
[root@mysql1 ~]# vim /etc/percona-xtradb-cluster.conf.d/mysqld.cnf
…
[mysqld]
server-id=11 //修改服务器标识(server-id=11)
datadir=/var/lib/mysql //工作目录
socket=/var/lib/mysql/mysql.sock //socket目录
log-error=/var/log/mysqld.log //日志目录
pid-file=/var/run/mysqld/mysqld.pid //进程目录
log-bin //开启binlog日志功能
log_slave_updates
expire_logs_days=7
…
[root@mysql2 ~]# rm -rf /var/lib/mysql/*
[root@mysql2 ~]# vim /etc/percona-xtradb-cluster.conf.d/mysqld.cnf
...
[mysqld]
server-id=12 //修改服务器标识(server-id=12)
datadir=/var/lib/mysql //工作目录
socket=/var/lib/mysql/mysql.sock //socket目录
log-error=/var/log/mysqld.log //日志目录
pid-file=/var/run/mysqld/mysqld.pid //进程目录
log-bin //开启binlog日志功能
log_slave_updates
expire_logs_days=7
...
[root@mysql3 ~]# rm -rf /var/lib/mysql/*
…
[mysqld]
server-id=13 //修改服务器标识(server-id=13)
datadir=/var/lib/mysql //工作目录
socket=/var/lib/mysql/mysql.sock //socket目录
log-error=/var/log/mysqld.log //日志目录
pid-file=/var/run/mysqld/mysqld.pid //进程目录
log-bin //开启binlog日志功能
log_slave_updates
expire_logs_days=7
…
② 分别修改3台服务器的mysqld_safe.cnf配置文件(使用默认配置即可)
[root@mysql1 ~]# vim /etc/percona-xtradb-cluster.conf.d/mysqld_safe.cnf
[mysqld_safe]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/lib/mysql/mysql.sock
nice = 0
[root@mysql2 ~]# vim /etc/percona-xtradb-cluster.conf.d/mysqld_safe.cnf
[mysqld_safe]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/lib/mysql/mysql.sock
nice = 0
[root@mysql3 ~]# vim /etc/percona-xtradb-cluster.conf.d/mysqld_safe.cnf
[mysqld_safe]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/lib/mysql/mysql.sock
nice = 0
③ 分别修改3台服务器的wsrep.cnf配置文件
[root@mysql1 ~]# vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
…
wsrep_cluster_address=gcomm://192.168.2.11,192.168.2.12,192.168.2.13 //集群成员
wsrep_node_address=192.168.2.11 //本节点IP地址
wsrep_cluster_name=pxc-cluster //集群名
wsrep_node_name=mysql1 //本节点名
wsrep_sst_auth="sstuser:NSD2021@tedu.cn" //SST数据同步授权用户及密码
…
[root@mysql2 ~]# vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
…
wsrep_cluster_address=gcomm://192.168.2.11,192.168.2.12,192.168.2.13 //集群成员
wsrep_node_address=192.168.2.12 //本节点IP地址
wsrep_cluster_name=pxc-cluster //集群名
wsrep_node_name=mysql2 //本节点名
wsrep_sst_auth="sstuser:NSD2021@tedu.cn" //SST数据同步授权用户及密码
…
[root@mysql3 ~]# vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
…
wsrep_cluster_address=gcomm://192.168.2.11,192.168.2.12,192.168.2.13 //集群成员
wsrep_node_address=192.168.2.13 //本节点IP地址
wsrep_cluster_name=pxc-cluster //集群名
wsrep_node_name=mysql3 //本节点名
wsrep_sst_auth="sstuser:NSD2021@tedu.cn" //SST数据同步授权用户及密码
…
步骤3:启动PXC服务
① 启动集群服务(首次启动服务时间比较长)(mysql1操作)
[root@mysql1 ~]# systemctl start mysql@bootstrap.service //启动集群服务(集群环境初始化)
[root@mysql1 ~]# netstat -nlptu | grep :3306 //数据库服务端口
tcp6 0 0 :::3306 :::* LISTEN 2419/mysqld
[root@mysql1 ~]# netstat -nlptu | grep :4567 //集群通信端口
tcp 0 0 0.0.0.0:4567 0.0.0.0:* LISTEN 2419/mysqld
# 初始化数据库服务密码
[root@mysql1 ~]# grep password /var/log/mysqld.log //查找日志生成随机登录密码
2021-06-16T03:12:37.699513Z 1 [Note] A temporary password is generated for root@localhost: +KduIl_.)655
[root@mysql1 ~]# mysqladmin -uroot -p'+KduIl_.)655' password 'NSD2021@tedu.cn';
# 添加授权SST数据同步授权用户sstuser(授权:reload,lock tables,replication client,process)
[root@mysql1 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> grant reload,lock tables,replication client,process on *.* to sstuser@'localhost' identified by 'NSD2021@tedu.cn';
Query OK, 0 rows affected, 1 warning (0.00 sec)
② 启动mysql2、mysql3节点的mysql服务,其它节点将会自动同步mysql1服务器的数据、root初始密码、授权用户sstuser
[root@mysql2 ~]# systemctl start mysql //注意:启动的是mysql服务,不是mysqld
[root@mysql2 ~]# netstat -utnlp | grep :3306 //数据库服务端口
tcp6 0 0 :::3306 :::* LISTEN 2968/mysqld
[root@mysql2 ~]# netstat -utnlp | grep :4567 //集群通信端口
tcp 0 0 0.0.0.0:4567 0.0.0.0:* LISTEN 2968/mysqld
[root@mysql3 ~]# systemctl start mysql //注意:启动的是mysql服务,不是mysqld
[root@mysql3 ~]# netstat -utnlp | grep :3306 //数据库服务端口
tcp6 0 0 :::3306 :::* LISTEN 2968/mysqld
[root@mysql2 ~]# netstat -utnlp | grep :4567 //集群通信端口
tcp 0 0 0.0.0.0:4567 0.0.0.0:* LISTEN 2968/mysqld
步骤4:测试配置
① 在任意数据库服务器查看集群信息
mysql> show status like "%wsrep%"; //查找到以下信息
+----------------------------------+-------------------------------------------------------+
| Variable_name | Value |
+----------------------------------+-------------------------------------------------------+
| wsrep_incoming_addresses | 192.168.2.11:3306,192.168.2.12:3306,192.168.2.13:3306 |
| wsrep_cluster_weight | 3 |
| wsrep_cluster_status | Primary |
| wsrep_connected | ON |
| wsrep_ready | ON |
+----------------------------------+-------------------------------------------------------+
71 rows in set (0.01 sec)
解释说明:
② 在任意数据库服务器访问集群,并授予测试用户(授予的用户,会同步到集群的其它成员)
mysql> grant all on db1.* to dbuser1@'%' identified by 'NSD2021@tedu.cn';
Query OK, 0 rows affected, 1 warning (0.48 sec)
mysql> show grants for dbuser1;
+--------------------------------------------------+
| Grants for dbuser1@% |
+--------------------------------------------------+
| GRANT USAGE ON *.* TO 'dbuser1'@'%' |
| GRANT ALL PRIVILEGES ON `db1`.* TO 'dbuser1'@'%' |
+--------------------------------------------------+
2 rows in set (0.00 sec)
③ 客户端192.168.2.5连接集群任意数据库服务器,创建库和表,并存取数据(mysql1)
[root@localhost ~]# mysql -udbuser1 -pNSD2021@tedu.cn -h192.168.2.11
mysql> create database db1 default charset utf8mb4;
Query OK, 1 row affected (0.01 sec)
mysql> create table db1.students(id int primary key auto_increment, name varchar(20));
Query OK, 0 rows affected (0.00 sec)
mysql> insert into db1.students(name) values ('tom');
Query OK, 1 row affected (0.01 sec)
④ 客户端192.168.2.5连接集群任意数据库服务器查看数据(mysql2、mysql3)
[root@localhost ~]# mysql -udbuser1 -pNSD2021@tedu.cn -h192.168.2.12
mysql> select * from db1.students;
+----+------+
| id | name |
+----+------+
| 1 | tom |
+----+------+
1 row in set (0.00 sec)
[root@localhost ~]# mysql -udbuser1 -pNSD2021@tedu.cn -h192.168.2.13
mysql> select * from db1.students;
+----+------+
| id | name |
+----+------+
| 1 | tom |
+----+------+
1 row in set (0.00 sec)
步骤5:测试故障自动恢复
① 情况1:停止mysql@bootstrap.service服务
[root@mysql1 ~]# systemctl stop mysql@bootstrap.service
# 在任意数据库服务器,存储数据并查看
[root@mysql2 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> insert into db1.students(name) values('jerry');
Query OK, 1 row affected (0.01 sec)
mysql> select * from db1.students;
+----+-------+
| id | name |
+----+-------+
| 1 | tom |
| 5 | jerry |
+----+-------+
2 rows in set (0.00 sec)
② 停止服务后,查看/var/lib/mysql/grastate.dat文件,与其它节点的seqno不一致
[root@mysql1 ~]# cat /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid: e74df6e9-ceb6-11eb-904b-d65cf985a2a7
seqno: 6
safe_to_bootstrap: 0
[root@mysql2 ~]# cat /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid: e74df6e9-ceb6-11eb-904b-d65cf985a2a7
seqno: -1
safe_to_bootstrap: 0
[root@mysql3 ~]# cat /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid: e74df6e9-ceb6-11eb-904b-d65cf985a2a7
seqno: -1
safe_to_bootstrap: 0
③ 停止集群其它的mysql服务器
[root@mysql2 ~]# systemctl stop mysql
[root@mysql3 ~]# systemctl stop mysql //最后一个退出关闭服务
④ 查看所有mysql服务器,找到具有最高seqno的节点,并设置safe_to_boostrap的值改为1
[root@mysql3 ~]# vim /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid: 50caf19c-ce5d-11eb-bb5b-5229ff45a12e
seqno: 10
safe_to_bootstrap: 1 //群集引导
[root@mysql3 ~]# systemctl start mysql@bootstrap.service
⑤ 再启动其它主机的mysql服务
[root@mysql1 ~]# systemctl start mysql
[root@mysql2 ~]# systemctl start mysql
⑥ 再次检查所有数据库服务器的/var/lib/mysql/grastate.dat文件,发现所有seqno值都同步了;
[root@mysql1 ~]# vim /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid: 50caf19c-ce5d-11eb-bb5b-5229ff45a12e
seqno: -1
safe_to_bootstrap: 0
验证:查看故障恢复的数据库服务器数据,已自动恢复
[root@mysql1 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> insert into db1.students(name) values('jerry');
Query OK, 1 row affected (0.01 sec)
mysql> select * from db1.students;
+----+-------+
| id | name |
+----+-------+
| 1 | tom |
| 5 | jerry |
+----+-------+
2 rows in set (0.00 sec)
① 情况2:停止mysql服务
[root@mysql2 ~]# systemctl stop mysql
② 停止服务后,查看/var/lib/mysql/grastate.dat文件,与其它节点的seqno不一致
[root@mysql2 ~]# cat /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid: e74df6e9-ceb6-11eb-904b-d65cf985a2a7
seqno: 9
safe_to_bootstrap: 0
[root@mysql1 ~]# cat /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid: e74df6e9-ceb6-11eb-904b-d65cf985a2a7
seqno: -1
safe_to_bootstrap: 0
③ 在任意数据库服务器,存储数据并查看
[root@mysql1 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> insert into db1.students(name) values('ben');
Query OK, 1 row affected (0.01 sec)
mysql> select * from db1.students;
+----+-------+
| id | name |
+----+-------+
| 1 | tom |
| 5 | jerry |
| 7 | ben |
+----+-------+
2 rows in set (0.00 sec)
④ 再次启动mysql服务
[root@mysql2 ~]# systemctl start mysql
⑤ 再次检查数据库服务器的/var/lib/mysql/grastate.dat文件,发现所有seqno值都同步了;
[root@mysql2 ~]# cat /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid: e74df6e9-ceb6-11eb-904b-d65cf985a2a7
seqno: -1
safe_to_bootstrap: 0
验证:查看故障恢复的数据库服务器数据,已自动恢复
[root@mysql2 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> insert into db1.students(name) values('ben');
Query OK, 1 row affected (0.01 sec)
mysql> select * from db1.students;
+----+-------+
| id | name |
+----+-------+
| 1 | tom |
| 5 | jerry |
| 7 | ben |
+----+-------+
2 rows in set (0.00 sec)
二、存储引擎
数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以获得特定的功能。现在许多不同的数据库管理系统都支持多种不同的数据引擎。MySQL支持很多存储引擎,包括MyISAM、InnoDB、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE等,其中InnoDB和BDB支持事务安全。
例如:查看数据库默认使用并支持的引擎
mysql> show engines; //DEFAULT表示默认使用的引擎
+--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+
| CSV | YES | CSV storage engine | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| InnoDB | DEFAULT | Percona-XtraDB, Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
+--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
例如:查看当前表使用的存储引擎
mysql> show create table db1.students\G
*************************** 1. row ***************************
Table: students
Create Table: CREATE TABLE `students` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
例如:创建表时指定使用的存储引擎
mysql> create table db1.students2(id int primary key auto_increment, name varchar(20)) engine=myisam;
Query OK, 0 rows affected (0.00 sec)
mysql> show create table db1.students2;
+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| students2 | CREATE TABLE `students2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 |
+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
三、读锁与写锁,行锁与表锁
1、读锁和写锁
无论何时,只要有多个SQL需要同一时刻修改数据,都会产生并发控制的问题。解决这类经典问题的方法就是并发控制,即在处理并发读或者写时,可以通过实现一个由两种类型的锁组成的锁系统来解决问题。这两种锁就是共享锁和排他锁,也叫读锁和写锁。
读锁(共享锁):
- 特性:读锁是共享的,多个用户可以在同一时刻读取同一资源,互不干扰。
- 作用:确保在读取数据时,数据不会被其他事务修改,从而保证数据的一致性。
写锁(排他锁):
- 特性:写锁是排他的,一个写锁会阻塞其他所有的写锁和读锁。
- 作用:确保在写入数据时,只有一个用户能够执行写操作,防止其他用户读取或修改正在写入的同一资源,从而保证数据的一致性和完整性。
锁的优先级:
- 写锁的优先级通常高于读锁,以确保写操作的及时性和数据的一致性。
2、行锁和表锁
实际数据库系统中每时每刻都在发生锁定,锁也是有粒度的,提高共享资源并发行的方式就是让锁更有选择性,尽量只锁定需要修改的部分数据,而不是所有的资源,因此要进行精确的锁定。由于加锁也需要消耗资源,包括获得锁、检查锁是否解除、释放锁等,都会增加系统的开销;所谓的锁策略就是要在锁的开销和数据的安全性之间寻求平衡,这种平衡也会影响性能。每种MySQL存储引擎都有自己的锁策略和锁粒度,最常用的两种重要的锁策略分别是表锁和行锁。
表锁:
- 特性:表锁是开销最小的锁策略,它会锁定整张表。
- 作用:当用户对表进行写操作时,需要先获得写锁,这会阻塞其他用户对该表的所有读写操作。只有在没有写锁的情况下,其他读取的用户才能获得读锁,读锁之间是不相互阻塞的。
- 优点:速度快,开销小。
- 缺点:冲突多,并发性较低。
行锁:
- 特性:行锁只对指定的记录加锁,其他进程仍然可以对同一表中的其他记录进行操作。
- 作用:行锁可以最大程度地支持并发处理,但也带来了最大的锁开销。
- 优点:冲突少,并发性高。
- 缺点:速度慢,开销大。
3、锁策略的平衡
锁策略的选择需要在锁的开销和数据的安全性之间寻求平衡。不同的MySQL存储引擎有不同的锁策略和锁粒度,常见的两种重要锁策略是表锁和行锁。
表锁:适用于读操作频繁、写操作较少的场景,因为表锁的开销小,速度快,但并发性较低。
行锁:适用于写操作频繁、需要高并发的场景,因为行锁的冲突少,并发性高,但开销大,速度慢
四、常见存储引擎
MySQL支持多种存储引擎,每种存储引擎都有其独特的特性和适用场景。以下是三种常见的存储引擎:MyISAM、InnoDB和MEMORY。
1. MyISAM
默认存储引擎:MySQL 5.5之前的默认存储引擎。
优势:访问速度快。
适用场景:对事务的完整性没有要求,或以select、insert为主的应用。在Web、数据仓库中应用广泛。
特点:
① 不支持事务、外键。
② 文件存储:每个MyISAM表在磁盘上存储为3个文件,文件名和表名相同,扩展名分别是:
- .frm:存储表定义(表结构)。
- .myd:MYData,存储数据。
- .myi:MYIndex,存储索引。
[root@mysql1 ~]# ls /var/lib/mysql/db1/
db.opt students2.frm students2.MYD students2.MYI
2.InnoDB
默认存储引擎:MySQL 5.5之后的默认存储引擎。
适用场景:对事务的完整性有较高要求,在并发条件下要求数据的一致性,数据操作中包含读、插入、删除、更新。在计费系统、财务系统等对数据的准确性要求较高的系统中被广泛应用。
优点:提供了具有提交(Commit)、回滚(Rollback)、崩溃恢复能力的事务安全,支持外键。
缺点:相比较于MyISAM,写的处理效率差一点,并且会占用更多的磁盘空间来存储数据和索引。
特点:
① 自动增长列:InnoDB表的自动增长列必须是索引,如果是组合索引,也必须是组合索引的第一列。MyISAM表的自动增长列可以是组合索引的其他列。
② 外键约束:MySQL的存储引擎中只有InnoDB支持外键约束。注意:当某个表被其它表创建了外键参照,那么该表对应的索引和主键禁止被删除。
3.MEMORY
存储方式:用保存在内存中的数据来创建表,每个MEMORY表对应一个磁盘文件,格式是.frm。
适用场景:内容变化不频繁的代码表,作为统计操作的中间结果表,便于利用它速率快的优势高效地对中间结果进行分析。
特点:
① 数据存储:数据存放在内存中,默认使用HASH索引,访问速度特别快。
② 缺点:数据库服务一旦关闭,数据就会丢失,另外对表的大小有限制。
扩展:MyISAM与InnoDB存储引擎的区别
事务支持:
- InnoDB:支持事务。
- MyISAM:不支持事务。
锁机制:
- InnoDB:支持行级锁。
- MyISAM:支持表级锁。
MVCC(多版本并发控制):
- InnoDB:支持MVCC。
- MyISAM:不支持MVCC。
外键支持:
- InnoDB:支持外键。
- MyISAM:不支持外键。
全文索引:
- InnoDB:不支持全文索引。
- MyISAM:支持全文索引。
MyISAM:适用于读操作频繁、对事务要求不高的场景,访问速度快,但不支持事务和外键。
InnoDB:适用于对事务完整性有较高要求、需要高并发和数据一致性的场景,支持事务、外键和行级锁,但占用更多磁盘空间。
MEMORY:适用于数据变化不频繁、需要快速访问的场景,数据存储在内存中,访问速度极快,但数据易丢失且表大小有限制。
思维导图:
小结:
本篇章节为【第四阶段】RDBMS2-DAY5 的学习笔记,这篇笔记可以初步了解到 PXC概述、部署PXC(自动故障恢复测试)、存储引擎、读锁/写锁、表锁/行锁、常用的存储引擎介绍,除此之外推荐参考相关学习网址:
- 带你玩转Mysql高可用方案--PXC_pxc架构图-CSDN博客
Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解。