PXC 、 MySQL存储引擎
回顾部署MHA集群步骤:
1、准备环境
1.1 公共配置:启用binlog日志 用户授权
半同步复制模式 禁止删除中继日志文件
1.2 ssh免密登录
1.2.1、 所有数据库服务器之间ssh免密登录
1.2.2、 管理主机要ssh免密登录所有数据库服务器
1.3 主从同步复制
配置一主多从同步结构
2、配置管理主机
3、配置数据库服务器
4、测试配置
5、启动管理服务
6、测试高可用功能
MHA集群缺点总结:
必须要有vip地址
宕机的主服务器需要手动添加到集群里,还需要手动同步宕机期间的数据
管理服务发现主服务器宕机后,会调用故障切换脚本,
把vip地址部署在新的主数据库服务器上。管理服务会
自动停止,需要手动启动管理服务器,才能监视新的主数据服务器
故障切换期间会有数据丢失的情况
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RDBMS2_DAY05
一 部署PXC集群
1.1 PXC介绍
Percona XtraDB Cluster(简称PXC)
是基于Galera的MySQL高可用集群解决方案
Galera Cluster是Codership公司开发的一套免费开源的高可用方案
PXC集群主要由两部分组成:
Percona Server with XtraDB和Write Set Replication patches(同步、多主复制插件)
官网http://galeracluster.com
1.2 pxc集群特点
1、数据强一致性、无同步延迟
2、没有主从切换操作,无需使用虚拟IP
3、支持InnoDB存储引擎
4、多线程复制
5、部署使用简单
6、支持节点自动加入,无需手动拷贝数据
1.3 相关端口号
3306 数据库服务端口
4444 SST 端口
4567 集群通信端口
4568 IST 端口
SST State Snapshot Transfer 全量同步
IST Incremental State Transfer 增量同步
2.4 环境准备
准备3台服务器(没有安装过任何数据库服务软件)
配置Ip地址 192.168.4.71 192.168.4.72 192.168.4.73
拷贝PXC软件 到 3台服务器 /root/
二 配置pxc集群
第1步:安装软件 (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
第2步:修改配置文件
2.1 指定集群中主机的server_id 修改 mysqld.cnf文件
2.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
第3步:初始化集群
说明:在任意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>
第4步:在72 和 73 主机 分别启动数据库服务,
启动服务后会自动同步71主机的数据
#在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服务
[root@pxcnode73 pxc]# ls /var/lib/mysql [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@pxcnode71 ~]#
#在集群中的任意主机查看集群状态
[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存储引擎 (80%是理论 着重在于理解)
2.1 存储引擎介绍
MySQL服务软件自带的功能程序
当对表里的数据做select 或insert 访问时,
会根据表使用的存储引擎对数据做处理。不同的存储引擎有不同的功能和数据存储方式。
作为可插拔式的组件提供
MySQL 5.0/5.1 (MyISAM)
MySQL 5.5/5.6 (InnoDB)
1)MySQL服务体系结构 (mysql服务的功能分类)
1 管理工具: 安装MySQL服务软件后,提供的管理命令
2连接池:验证客户端连接时使用的用户和密码是否正确 同时验证数据库服务器是否有mysqld进程相应连接
3 SQL接口: 把用户执行的SQL命令传递给本机的mysqld 进程
4分析器:检查SQL命令的语句及对数据的访问权限
5优化器:对要执行的 SQL命令做优化(是内存自动功能程序)
6查询缓存:划分出一定的物理内存空间给MySQL服务存储查找过的数据。
7存储引擎:当对表里的数据做查询(select) 或写操作(insert /update /delete)会调用存储引擎对表中的数据做处理,至于如何处理取决表使用的存储引擎的功能
8文件系统:通常指的就是电脑的硬盘
2)MySQL服务的工作过程
2.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.2 处理存储(insert)访问的工作过程
第1步: 客户端向服务器发起连接请求
第2步: 服务器接收到客户端连接请求并响应
第3步: 根据表使用的存储引擎 对表中的数据做对应的处理。
第4步: 断开连接
2.2 存储引擎管理
1) 查看存储引擎
1.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>
1.2 查看当前已有表使用的存储引擎
mysql> show create table DB1.t3 \G
2) 修改存储引擎
2.1 修改数据库服务默认使用的存储引擎
[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>
2.2建表时指定表使用的存储引擎
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>
2.3修改表使用的存储引擎(一般在表存储存储数据之前修改)
说明:存储引擎修改了,存储数据的位置也会改变,
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>
2.3 常用存储引擎特点(生产环境下常用的存储引擎)
1) myisam存储引擎特点
支持表级锁 、不支持事务、事务回滚、外键
myisam存储引擎的表 每个表对应3个表文件
表名.frm 存储表头信息 mysql> desc 库.表;
表名.MYI 存储表索引信息 mysql> show index from 库.表;
表名.MYD 存储表里的数据 mysql> select * from 库.表;
2) innodb存储引擎特点
支持行级、支持事务、事务回滚、外键
innodb存储引擎的表 每个表对应2个表文件
表名.frm 存储表头信息 mysql> desc 库.表;
表名.ibd 存储表的索引信息+表的数据信息
show index from 库.表; + select * from 库.表;
3) 专业术语
说明: 给表加锁,是为了解决客户端并发访问的冲突问题
3.1 锁类型:根据对数据的访问类型加锁
读锁:又称为共享锁,对数据做查询select 访问
加了读锁表,允许多个访问同时查询一张。
写锁:又称为排它锁或互斥锁,对数据做写访问(写访问通常指定的是 insert | delete | update )加了写锁的表,同一时间只允许1个连接做写操作,后续的读和写都得等待,等待写锁释放后,才允许后续的读或写访问。
3.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)
2.4 事务特性
1)什么是事务?
指的是一组不可分割的SQL操作。
使用Innodb 存储引擎的表才支持事务。
事务用来管理对数据的 insert,update,delete 操作
2) 事务的特性简称ACID (表的存储引擎必须是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) mysql>
回到第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>
2.5 事务隔离级别
事务隔离解决的问题:脏读 、不可重复读 、 幻读 。
脏读: 读到了其他事务未提交的数据,读到的数据并不一定是最终存储到数据库里的数据。
可重复读:可重复读指的是在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据都是一致的。
不可重复读:一个事务先后读取同一条记录,而事务在两次读取之间该数据被其它事务所修改,则两次读取的数据不同,这种就是不可重复读。
幻读:一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为幻读。
事务隔离级别
读未提交(Read Uncommitted): 最低的隔离级别,允许读取尚未提交的数据变更;可能会导致脏读、幻读、不可重复对。
读提交(Read Committed):允许并发事务读取已经提交的数据,可以阻止脏读;但幻读或不可重复读仍有可能发生。
可重复读(Repeatable Read):对同一字段的多次读取结果都是一致的;除非数据是被本身事务自己所修改;可以阻止脏读和不可重复读,但幻读仍有可能发生。
序列化(Serializable):最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,事务之间完全不可能产生干扰。该级别可以防止脏读和不可重复读,及幻读。
2.5.3 隔离级别演示
第一个连接:
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;
over