Percona XtraDB Cluster(简称PXC)
是基于Galera的MySQL高可用集群解决方案
Galera Cluster是Codership公司开发的一套免费开源的高可用方案
PXC集群主要由两部分组成:
Percona Server with XtraDB
和Write Set Replication patches
(同步、多主复制插件)
官网http://galeracluster.com
1.数据强一致性、无同步延迟
2.没有主从切换操作,无需使用虚拟IP
3.支持InnoDB存储引擎
4.多线程复制
5.部署使用简单
6.支持节点自动加入,无需手动拷贝数据
端口 | 说明 |
---|---|
3306 | 数据库服务端口 |
4444 | SST端口 |
4567 | 集群通信端口 |
4568 | IST端口 |
SST | (State Snapshot Transfer) 全量同步 |
IST | (Incremental State Transfer) 增量同步 |
准备3台服务器(没有安装过任何数据库服务软件)
配置Ip地址 192.168.4.71 192.168.4.72 192.168.4.73
拷贝PXC软件 到 3台服务器 /root/
主机名 | IP地址 | 角色 |
---|---|---|
pxcnode71 | 192.168.4.71 | 数据库服务器 |
pxcnode72 | 192.168.4.72 | 数据库服务器 |
pxcnode73 | 192.168.4.73 | 数据库服务器 |
软件介绍:
软件 | 作用 |
---|---|
percona-xtrabackup-24-2.4.13-1.el7.x86_64.rpm | 在线热备程序 |
qpress-1.1-14.11.x86_64.rpm | 递归压缩程序 |
Percona-XtraDB-Cluster-5.7.25-31.35-r463-el7-x86_64-bundle.rpm | 集群服务程序 |
(3台主机都要安装)
必须按照顺序安装 因为软件之间有依赖
]# cd pxc/
]# yum -y install libev-4.15-1.el6.rf.x86_64.rpm
]# yum -y install percona-xtrabackup-24-2.4.13-1.el7.x86_64.rpm
]# yum -y install qpress-1.1-14.11.x86_64.rpm
]# tar -xf Percona-XtraDB-Cluster-5.7.25-31.35-r463-el7-x86_64-bundle.tar
]# yum -y install Percona-XtraDB-Cluster-*.rpm
相关配置文件:
/etc/percona-xtradb-cluster.conf.d #所在目录
配置文件说明:
mysqld.cnf #数据库服务运行参数配置文件
mysqld_safe.cnf #Percona Server 5.7配置文件
wsrep.cnf #PXC集群配置文件
1 指定集群中主机的server_id, 修改 mysqld.cnf文件
2 指定集群信息, 修改 wsrep.cnf文件
#修改71主机的server_id
vim /etc/percona-xtradb-cluster.conf.d/mysqld.cnf
server_id=71
#修改72主机的server_id
vim /etc/percona-xtradb-cluster.conf.d/mysqld.cnf
server_id=72
#修改73主机的server_id
vim /etc/percona-xtradb-cluster.conf.d/mysqld.cnf
server_id=73
#修改71主机的wsrep.cnf 文件
]# vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
8 wsrep_cluster_address=gcomm://192.168.4.71,192.168.4.72,192.168.4.73
25 wsrep_node_address=192.168.4.71
27 wsrep_cluster_name=pxc-cluster
30 wsrep_node_name=pxcnode71
39 wsrep_sst_auth="sstuser:123qqq...A"
:wq
#修改72主机的wsrep.cnf 文件
]# vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
8 wsrep_cluster_address=gcomm://192.168.4.71,192.168.4.72,192.168.4.73
25 wsrep_node_address=192.168.4.72
27 wsrep_cluster_name=pxc-cluster
30 wsrep_node_name=pxcnode72
39 wsrep_sst_auth="sstuser:123qqq...A"
:wq
#修改73主机的wsrep.cnf 文件
]# vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
8 wsrep_cluster_address=gcomm://192.168.4.71,192.168.4.72,192.168.4.73
25 wsrep_node_address=192.168.4.73
27 wsrep_cluster_name=pxc-cluster
30 wsrep_node_name=pxcnode73
39 wsrep_sst_auth="sstuser:123qqq...A"
:wq
说明:在任意1台服务器上执行初始化集群操作都可以(仅需要执行一遍)
统一在71 主机执行 ,具体步骤如下:
1、启动服务
2、使用初始密码连接服务
3、添加授权用户sstuser
4、查看数据库服务器端口 3306
5、查看集群端口4567
6、管理员root 登录 建库表存储记录
[root@pxcnode71 ~]# systemctl start mysql@bootstrap.service #初始化集群
[root@pxcnode71 ~]# ls /var/lib/mysql #查看数据数据库文件列表 有文件说明成功
auto.cnf gvwstate.dat mysqld_safe.pid pxcnode71-bin.000002
ca-key.pem ib_buffer_pool mysql.sock pxcnode71-bin.index
ca.pem ibdata1 mysql.sock.lock server-cert.pem
client-cert.pem ib_logfile0 performance_schema server-key.pem
client-key.pem ib_logfile1 private_key.pem sys
galera.cache ibtmp1 public_key.pem xb_doublewrite
grastate.dat mysql pxcnode71-bin.000001
[root@pxcnode71 ~]#
[root@pxcnode71 ~]# grep password /var/log/mysqld.log #查看管理员初始化密码
2021-11-22T02:49:33.621967Z 1 [Note] A temporary password is generated for root@localhost: UfjF5UQGb/fq
[root@pxcnode71 ~]#
[root@pxcnode71 ~]# mysql -uroot -p'UfjF5UQGb/fq' #初始密码登录
mysql> alter user root@"localhost" identified by "123456"; 强制修改密码
mysql> exit 断开连接
Bye
[root@pxcnode71 ~]# mysql -uroot -p123456 #使用修改后的密码登录
mysql> grant all on *.* to sstuser@"localhost" identified by "123qqq...A"; 添加全量同步用户sstuser
Query OK, 0 rows affected, 1 warning (0.10 sec)
mysql> exit
Bye
[root@pxcnode71 ~]# netstat -utnalp | grep 3306 #查看数据库服务端口
tcp6 0 0 :::3306 :::* LISTEN 5359/mysqld
[root@pxcnode71 ~]#
[root@pxcnode71 ~]# netstat -utnalp | grep 4567 #查看集群端口
tcp 0 0 0.0.0.0:4567 0.0.0.0:* LISTEN 5359/mysqld
[root@pxcnode71 ~]#
[root@pxcnode71 ~]# mysql -uroot -p123456 #管理员登录,建库表存储记录
mysql> create database db1;
mysql> create table db1.a(id int primary key auto_increment,age int); #pxc集群中的表必须要有主键 自增长可选
mysql> insert into db1.a(age)values(18),(24),(29);
mysql> select * from db1.a;
+----+------+
| id | age |
+----+------+
| 1 | 18 |
| 2 | 24 |
| 3 | 29 |
+----+------+
3 rows in set (0.00 sec)
mysql>
启动服务后会自动同步71主机的数据
#在72主机启动mysql服务
#在72主机启动mysql服务
[root@pxcnode72 ~]# systemctl start mysql
[root@pxcnode72 ~]# ls /var/lib/mysql
auto.cnf ib_logfile0 pxcnode72-bin.000001
ca-key.pem ib_logfile1 pxcnode72-bin.index
ca.pem ibtmp1 server-cert.pem
client-cert.pem innobackup.move.log server-key.pem
client-key.pem innobackup.prepare.log sys
db1 mysql xb_doublewrite
galera.cache mysql.sock xtrabackup_binlog_pos_innodb
grastate.dat mysql.sock.lock xtrabackup_galera_info
gvwstate.dat performance_schema xtrabackup_info
ib_buffer_pool private_key.pem xtrabackup_master_key_id
ibdata1 public_key.pem
[root@pxcnode72 ~]# netstat -utnalp |grep 3306
tcp6 0 0 :::3306 :::* LISTEN 5443/mysqld
[root@pxcnode72 ~]# netstat -utnalp |grep 4567
tcp 0 0 0.0.0.0:4567 0.0.0.0:* LISTEN 5443/mysqld
tcp 0 0 192.168.4.72:4567 192.168.4.72:41634 CLOSE_WAIT 5443/mysqld
tcp 0 0 192.168.4.72:52306 192.168.4.71:4567 ESTABLISHED 5443/mysqld
[root@pxcnode72 ~]#
[root@pxcnode72 ~]# mysql -uroot -p123456 -e 'select * from db1.a'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+------+
| id | age |
+----+------+
| 1 | 18 |
| 2 | 24 |
| 3 | 29 |
+----+------+
[root@pxcnode72 ~]#
#在73主机启动mysql服务
#在73主机启动mysql服务
[root@pxcnode73 pxc]# ls /var/lib/mysql
[root@pxcnode73 pxc]#
[root@pxcnode73 pxc]# systemctl start mysql
[root@pxcnode73 pxc]# ls /var/lib/mysql
auto.cnf ib_logfile0 pxcnode73-bin.000001
ca-key.pem ib_logfile1 pxcnode73-bin.index
ca.pem ibtmp1 server-cert.pem
client-cert.pem innobackup.move.log server-key.pem
client-key.pem innobackup.prepare.log sys
db1 mysql xb_doublewrite
galera.cache mysql.sock xtrabackup_binlog_pos_innodb
grastate.dat mysql.sock.lock xtrabackup_galera_info
gvwstate.dat performance_schema xtrabackup_info
ib_buffer_pool private_key.pem xtrabackup_master_key_id
ibdata1 public_key.pem
[root@pxcnode73 pxc]# netstat -utnalp | grep 3306
tcp6 0 0 :::3306 :::* LISTEN 5383/mysqld
[root@pxcnode73 pxc]# netstat -utnalp | grep 4567
tcp 0 0 0.0.0.0:4567 0.0.0.0:* LISTEN 5383/mysqld
tcp 0 0 192.168.4.73:32956 192.168.4.71:4567 ESTABLISHED 5383/mysqld
tcp 0 0 192.168.4.73:4567 192.168.4.73:43872 CLOSE_WAIT 5383/mysqld
tcp 0 0 192.168.4.73:42526 192.168.4.72:4567 ESTABLISHED 5383/mysqld
[root@pxcnode73 pxc]#
[root@pxcnode73 pxc]# mysql -uroot -p123456 -e 'select * from db1.a'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+------+
| id | age |
+----+------+
| 1 | 18 |
| 2 | 24 |
| 3 | 29 |
+----+------+
[root@pxcnode73 pxc]#
1、查看mysql服务的父进程pid 通过kill -9 杀死父进程
]# which pstree || yum -y install psmisc
]# pstree -p | grep mysqld
]# kill -9 pid号
2、清空数据库目录 rm -rf /var/lib/mysql/*
3、检查 mysqld.cnf 和 wsrep.cnf 文件的配置项目
4、检查 防火墙和 selinux服务关闭了吗
如果初始集群失败,就重新执行集群初始化
如果启动MySQL服务错误,就重新执行启动mysql服务
**第1步:**连接集群中的任意主机存取数据
#在任意服务器添加客户端连接数据库服务使用的用户
#在客户端连接数据库服务
#查看数据是否同步
#在73主机 添加yaya用户
[root@pxcnode73 ~]# mysql -uroot -p123456 -e 'grant select,insert on db1.* to yaya@"%" identified by "123456"'
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@pxcnode73 ~]#
#客户端50连接集群中的任意主机 访问数据
[root@host50 ~]# mysql -h192.168.4.71 -uyaya -p123456 -e 'select * from db1.a'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+------+
| id | age |
+----+------+
| 1 | 18 |
| 2 | 24 |
| 3 | 29 |
+----+------+
[root@host50 ~]#
#客户端连接72主机
[root@host50 ~]# mysql -h192.168.4.72 -uyaya -p123456 -e 'insert into db1.a(age) values(33)'
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@host50 ~]#
#客户端连接73主机
[root@host50 ~]# mysql -h192.168.4.73 -uyaya -p123456 -e 'insert into db1.a(age) values(33)'
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@host50 ~]#
[root@host50 ~]# mysql -h192.168.4.71 -uyaya -p123456 -e 'insert into db1.a(age) values(33)'
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@host50 ~]#
#客户端连接71
[root@host50 ~]# mysql -h192.168.4.71 -uyaya -p123456 -e 'select * from db1.a'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+------+
| id | age |
+----+------+
| 1 | 18 |
| 2 | 24 |
| 3 | 29 |
| 4 | 33 |
| 6 | 33 |
| 8 | 33 |
+----+------+
第2步: 集群中只要有1台数据库服务器是正常的,就能提供存取功能
#停止任意2台主机的数据库服务,
#都可以访问剩下的一台服务器存取数据
[root@pxcnode71 ~]# systemctl stop mysql@bootstrap.service
# 在集群中的任意主机查看集群状态
[root@pxcnode72 ~]# mysql -uroot -p123456 -e 'show status like "%wsrep%"'
wsrep_incoming_addresses | 192.168.4.72:3306,192.168.4.73:3306 |
wsrep_cluster_size | 2
wsrep_cluster_status | Primary |
wsrep_connected | ON
# 停止73主机的数据库服务
[root@pxcnode73 ~]# systemctl stop mysql
[root@pxcnode73 ~]#
# 再次查看集群状态 ,并对数据库做操作(insert 或select )
[root@pxcnode72 ~]# mysql -uroot -p123456 -e 'show status like "%wsrep%"'
[root@pxcnode72 ~]# mysql -uroot -p123456 -e 'insert into db1.a(age) values(100)'
[root@pxcnode72 ~]# mysql -uroot -p123456 -e 'insert into db1.a(age) values(100)'
[root@pxcnode72 ~]# mysql -uroot -p123456 -e 'insert into db1.a(age) values(100)'
第3步: 宕机的服务器启动后会自动加入集群并同步宕机期间的数据
#分别启动71 和 73 主机的数据库服务
[root@pxcnode71 ~]# systemctl start mysql
[root@pxcnode73 ~]# systemctl start mysql
#客户端连接71 或 73 查看数据
[root@host50 ~]# mysql -h192.168.4.73 -uyaya -p123456 -e 'select * from db1.a'
[root@host50 ~]# mysql -h192.168.4.71 -uyaya -p123456 -e 'select * from db1.a'
#随便连接1台数据库查看集群状态
[root@pxcnode72 ~]# mysql -uroot -p123456 -e 'show status like "%wsrep%"'
wsrep_incoming_addresses 192.168.4.72:3306,192.168.4.71:3306,192.168.4.73:3306 wsrep_cluster_size 3
MySQL服务软件自带的功能程序
当对表里的数据做select 或insert 访问时,
会根据表使用的存储引擎对数据做处理。不同的存储引擎有不同的功能和数据存储方式。
作为可插拔式的组件提供
MySQL 5.0/5.1 (MyISAM)
MySQL 5.5/5.6 (InnoDB)
1 管理工具: 安装MySQL服务软件后,提供的管理命令
2 连接池:验证客户端连接时使用的用户和密码是否正确 同时验证数据库服务器是否有mysqld进程相应连接
3 SQL接口: 把用户执行的SQL命令传递给本机的mysqld 进程
4 分析器:检查SQL命令的语句及对数据的访问权限
5 优化器:对要执行的 SQL命令做优化(是内存自动功能程序)
6 查询缓存:划分出一定的物理内存空间给MySQL服务存储查找过的数据。
7 存储引擎:当对表里的数据做查询(select) 或写操作(insert /update /delete)会调用存储引擎对表中的数据做处理,至于如何处理取决表使用的存储引擎的功能
8 文件系统:通常指的就是电脑的硬盘
(1) 处理查询select访问的工作过程
第1步: 客户端向服务器发起连接请求
第2步: 服务器接收到客户端连接请求并响应
第3步:
如果客户端执行的selcet 访问,先在查询缓存里提取数据
回复给客户端,
如果数据库服务器在查询缓存里没有找到用户访问的数据,这
时就要到数据库服务器的表里查找数据,对数据库目录下的表
做访问是就会调用表使用的存储引擎对表做处理,
然后把查找到的数据先放到查询缓存 在回复给客户端
第4步:断开连接
在数据库服务器查看与查询缓存相关的配置项
mysql> show variables like "%query_cache%";
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| have_query_cache | YES |
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 1048576 |
| query_cache_type | OFF | #默认就没有启用查询缓存
| query_cache_wlock_invalidate | OFF |
+------------------------------+---------+
(2) 处理存储(insert)访问的工作过程
第1步: 客户端向服务器发起连接请求
第2步: 服务器接收到客户端连接请求并响应
第3步: 根据表使用的存储引擎 对表中的数据做对应的处理。
第4步: 断开连接
mysql> show table status from 库名 where name="表名" \G # 查看表
mysql> show engins; # 查看服务
修改数据库服务使用的存储引擎:
]# vim /etc/my.cnf
[mysqld]
default-storage-engine=存储引擎
:wq
]# systemctl restart mysqld
表存储引擎的指定与修改:
mysql> create table 库.表(字段列表......) engine=存储引擎名; #创建时指定存储引擎
mysql> alter table 库.表 engine=存储引擎名; # 修改引擎名
1.查看数据库服务支持的存储引擎和默认使用的存储引擎
mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | 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 |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
mysql>
2.查看当前已有表使用的存储引擎
mysql> show create table DB1.t3 \G
[root@host50 ~]#vim /etc/my.cnf
[mysqld]
default-storage-engine=myisam
:wq
[root@host50 ~]# systemctl restart mysqld
[root@host50 ~]# mysql -uroot -pNSD2107...a
mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB | YES | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| MyISAM | DEFAULT | MyISAM storage engine | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
mysql>
**说明:**建表时,不指定表使用的存储引擎,使用默认存储引擎
表使用的存储引擎不同,存储方式和使用MySQL服务的功能都不一样
mysql> create database db10;
mysql> create table db10.a(id int);
mysql> show create table db10.a \G
*************************** 1. row ***************************
Table: a
Create Table: CREATE TABLE `a` (
`id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql>
mysql> create table db10.b(name char(10))engine = innodb;
mysql> create table db10.c(addr char(10))engine = memory;
说明:
memory存储引擎的表 每个表对应1个表文件
innodb存储引擎的表 每个表对应2个表文件
myisam存储引擎的表 每个表对应3个表文件
mysql> system ls /var/lib/mysql/db10/a.*
/var/lib/mysql/db10/a.frm /var/lib/mysql/db10/a.MYD /var/lib/mysql/db10/a.MYI
mysql> system ls /var/lib/mysql/db10/b.*
/var/lib/mysql/db10/b.frm /var/lib/mysql/db10/b.ibd
mysql>
mysql> system ls /var/lib/mysql/db10/c.*
/var/lib/mysql/db10/c.frm
mysql>
(一般在表存储存储数据之前修改)
**说明:**存储引擎修改了,存储数据的位置也会改变,
mysql> alter table db10.c engine=myisam;
mysql> system ls /var/lib/mysql/db10/c.*
/var/lib/mysql/db10/c.frm /var/lib/mysql/db10/c.MYD /var/lib/mysql/db10/c.MYI
mysql>
1.主要特点
支持表级锁 、不支持事务、事务回滚、外键
2.表文件
myisam存储引擎的表 每个表对应3个表文件
表名.frm 存储表头信息 mysql> desc 库.表;
表名.MYI 存储表索引信息 mysql> show index from 库.表;
表名.MYD 存储表里的数据 mysql> select * from 库.表;
1.主要特点
支持行级、支持事务、事务回滚、外键
2.表文件
innodb存储引擎的表 每个表对应2个表文件
表名.frm 存储表头信息 mysql> desc 库.表;
表名.ibd 存储表的索引信息+表的数据信息
show index from 库.表; + select * from 库.表;
3.事务日志文件
ibdata1
ib_logfile0
ib_logfile1
说明: 给表加锁,是为了解决客户端并发访问的冲突问题
1.读锁:
又称为共享锁,对数据做查询select 访问
加了读锁表,允许多个访问同时查询一张。
2.写锁:
又称为排它锁或互斥锁,对数据做写访问(写访问通常指定的是 insert | delete | update )
加了写锁的表,同一时间只允许1个连接做写操作,后续的读和写都得等待,等待写锁释放后,才允许后续的读或写访问。
1.行级锁: 仅仅对被访问的行分别加锁,没有被访问的行不加锁
2.表级锁: 对整张表加锁,只要是对表做访问,就会把整张表加锁(不管访问的是1行 还是更多行)
mysql> show create table db10.b \G
*************************** 1. row ***************************
Table: b
Create Table: CREATE TABLE `b` (
`name` char(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql>
第一连接 给表加锁
mysql> lock tables db10.b write;
Query OK, 0 rows affected (0.00 sec)
第二连接 对加锁的表做访问,加锁期间访问要等待
mysql> insert into db10.b values("aa"); 等待MySQL服务处理
第一连接 解锁
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
第二连接 插入命令执行完毕
mysql> insert into db10.b values("aa");
Query OK, 1 row affected (38.17 sec)
mysql> select * from db10.b;
+------+
| name |
+------+
| aa |
+------+
1 row in set (0.00 sec)
指的是一组不可分割的SQL操作。
使用Innodb 存储引擎的表才支持事务。
事务用来管理对数据的 insert,update,delete 操作
(表的存储引擎必须是innodb 才有事务的特性)
Atomic :原子性
一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成。
Consistency : 一致性
在事务开始之前和事务结束以后,数据库的完整性不会被破坏。
执行sql命令时,敲回车前 称为事务开始之前
执行sql命令时,敲回车后 称为事务结束以后
Isolation :隔离性
数据库允许多个并发事务同时对其数据进行读写和修改而互不影响。
MySQL服务是支持多并连接的服务,同一时刻可是同时接收多个客户端的访问,
如果访问的是innodb存储引擎的表,彼此不知道操作的是同1张表
Durability :持久性
事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
执行回车后,事务就结束。数据会永久有效。
第1个连接:
#创建银行表 并存储记录
create table tarena.bank(
id int primary key,
name varchar(20),
balance int
)engine=innodb;
insert into tarena.bank values(1,"jim",10000),(2,"tom",20000);
select * from tarena.bank;
#关闭自动提交功能
set autocommit=0;
show variables like "autocommit";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | OFF |
+---------------+-------+
1 row in set (0.00 sec)
#对表中的数据做修改
update tarena.bank set balance=balance-800 where id = 1;
update tarena.bank set balance=balance+800 where id = 2;
mysql> select * from tarena.bank;
+----+------+---------+
| id | name | balance |
+----+------+---------+
| 1 | jim | 9200 |
| 2 | tom | 20800 |
+----+------+---------+
2 rows in set (0.00 sec)
打开新终端连接数据库服务访问bank 表
看不到数据被修改了 , 因为 第一个连接修改数据 并没有执行提交
mysql> select * from tarena.bank;
+----+------+---------+
| id | name | balance |
+----+------+---------+
| 1 | jim | 10000 |
| 2 | tom | 20000 |
+----+------+---------+
2 rows in set (0.00 sec)
回到第1个终端
#回滚修改
mysql> rollback;
Query OK, 0 rows affected (0.03 sec)
#查看数据
mysql> select * from tarena.bank;
+----+------+---------+
| id | name | balance |
+----+------+---------+
| 1 | jim | 10000 |
| 2 | tom | 20000 |
+----+------+---------+
2 rows in set (0.00 sec)
#执行了commit 之后无法回滚 数据永久生效
mysql> delete from tarena.bank where id=2;
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.07 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from tarena.bank;
+----+------+---------+
| id | name | balance |
+----+------+---------+
| 1 | jim | 10000 |
+----+------+---------+
1 row in set (0.00 sec)
mysql>
1.脏读: 读到了其他事务未提交的数据,读到的数据并不一定是最终存储到数据库里的数据。
2.可重复读:可重复读指的是在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据都是一致的。
3.不可重复读:一个事务先后读取同一条记录,而事务在两次读取之间该数据被其它事务所修改,则两次读取的数据不同,这种就是不可重复读。
4.幻读:一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为幻读。
1.读未提交(Read Uncommitted):
最低的隔离级别,允许读取尚未提交的数据变更;可能会导致脏读、幻读、不可重复对。
2,读提交(Read Committed):
允许并发事务读取已经提交的数据,可以阻止脏读;但幻读或不可重复读仍有可能发生。
3.可重复读(Repeatable Read):
对同一字段的多次读取结果都是一致的;除非数据是被本身事务自己所修改;可以阻止脏读和不可重复读,但幻读仍有可能发生。
4.序列化(Serializable):
最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,事务之间完全不可能产生干扰。该级别可以防止脏读和不可重复读,及幻读。
从上至下,隔离强度主键增强,性能逐渐变差。
采用哪种隔离级别要根据系用需求权衡决定,
其中,可重复读是MySQL的默认级别
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(Read Uncommitted) | 可能 | 可能 | 可能 |
读提交(Read Committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable Read) | 不可能 | 不可能 | 可能 |
序列化(Serializable) | 不可能 | 不可能 | 不可能 |
第1个连接:
1 关闭自动提交功能 set autocommit=0;
2 对innodb存储引擎的表做修改 update tarena.bank set balance=20000 where id=1;
3 查看自己的修改 select * from tarena.bank;
(提醒 没有执行提交命令)
第2个连接:
1 查看当前的事务隔离级别 默认是可重复读
select @@tx_isolation;
2 执行查看表记录 发现看不到对方的修改
select * from tarena.bank;
3 把事务隔离级别修改为读未提交
set session transaction isolation level read uncommitted ;
4 执行查看表记录 发现可以看到对方的修改
select * from tarena.bank;
从上至下,隔离强度主键增强,性能逐渐变差。
采用哪种隔离级别要根据系用需求权衡决定,
其中,可重复读是MySQL的默认级别
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(Read Uncommitted) | 可能 | 可能 | 可能 |
读提交(Read Committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable Read) | 不可能 | 不可能 | 可能 |
序列化(Serializable) | 不可能 | 不可能 | 不可能 |
第1个连接:
1 关闭自动提交功能 set autocommit=0;
2 对innodb存储引擎的表做修改 update tarena.bank set balance=20000 where id=1;
3 查看自己的修改 select * from tarena.bank;
(提醒 没有执行提交命令)
第2个连接:
1 查看当前的事务隔离级别 默认是可重复读
select @@tx_isolation;
2 执行查看表记录 发现看不到对方的修改
select * from tarena.bank;
3 把事务隔离级别修改为读未提交
set session transaction isolation level read uncommitted ;
4 执行查看表记录 发现可以看到对方的修改
select * from tarena.bank;