一、MySQL并发访问控制
1.并发控制机制
(1)锁机制
资源竞争时候,多个线程表示多个用户会话;通过读写锁机制实现
读锁:共享锁,可以多个用户同时读取同一资源文件
写锁:独占锁,当一个用户对资源文件进行写操作时,其他线程既不能读也不能写
(2)锁粒度
表级锁:对于整个表进行的锁操作,并发处理有限,在线事务处理读写一样多时会出问题
行级锁:对于部分资源的锁操作
(3)锁策略
在锁粒度及数据安全性寻求的平衡机制;每种存储引擎都可以自行实现其锁策略和锁粒度;
MySQL在服务器级也实现了锁,表级锁;而Innodb自行实现了行级锁,而无需人为干预
(4)锁分类
隐式锁:由存储引擎自动施加锁;
显式锁:手动添加
2.命令行施加锁
(1) LOCK TABLES tbl_name[[AS] alias] lock_type [, tbl_name [[AS] alias] lock_type] … READ[LOCAL] | [LOW_PRIORITY] WRITE
指明锁定表和锁类型,可一次指明多个表,还可以加别名;服务器层面表级别锁
lock_type所类型:READ、WRITE
UNLOCKTABLES;
(2)FLUSH TABLEStb_name[,...] [WITH READ LOCK] [FOR UPDATE]
FLUSH 清理,把表写到磁盘关闭再打开
UPDATE更新
(3) SELECT clase[FOR UPDATE] [WITH READ LOACK]
二、MySQL事务操作
1.ACID测试
A:atomicity,原子性;整个事务中的所有操作要么全部成功执行,要么全部失败后回滚;
C:consistency,一致性;数据库总是从一个一致性状态转换为另一个一致性状态;
I:Isolation,隔离性;一个事务所做出的操作在提交之前,是不能为其它所见;隔离有多种隔离级别;
隔离级别越高,意味着数据安全性越高,但并发性越低
D:durability:持久性;一旦事务提交,其所做的修改会永久保存于数据库中;
2.事务概念
事务是一组原子性的SQL查询语句,是一个独立工作单元。当操作需要多步骤完成时候,为了保证安全或者数据完整性而引入的机制,其执行的一组语句要么全部都执行,要么在无法中断时候能够回顾,使得数据还原。
例如:银行系统中的转账操作需要保证事务一致
3.事务流程
第一步:显示启动事务语句:START TRANSACTION;
...执行的SQL语句
...
第二步:结束事务方式:
(1) COMMIT:提交,写入到数据库文件中确保永久有效
(2) ROLLBACK: 回滚
注意:
1) 只有事务型存储引擎方能支持此类操作;例如Inoodb支持事务、MyISAM不支持事务
2) 建议显式请求和提交事务,而不要使用“自动提交autocommit”功能,每一次提交都会进行IO操作,降低系统性能
MariaDB[(none)]> SHOW GLOBAL VARIABLES LIKE 'autocommit';
autocommit={1|0},0表示关闭off
临时修改实例:
MariaDB [(none)]> SET SESSIONautocommit=0; # 设置会话界别的自动提交
MariaDB[(none)]> SHOW VARIABLES LIKE'autocommit';
3) 事务支持savepoint(保存点),在进行中加入保存点可以指定点回滚,若无savepoint则必须回滚到起始处
SAVEPOINT identifier 指明标识符
ROLLBACK [WORK] TO[SAVEPOINT] identifier 回滚到标识点
RELEASE SAVEPOINTidentifier 删除标识点
实例:
MariaDB[(none)]> SAVEPOINT sp1
MariaDB[(none)]> SAVEPOINT sp2
MariaDB[(none)]> SAVEPOINT sp3
MariaDB[(none)]> ROLLBACK TO sp2
4.事务隔离级别:mysql支持到第三级别
(1)隔离级别
READ UNCOMMITTED (读未提交):问题一、二、三
READ COMMITTED (读提交):问题二、三
REPEATABLE READ (可重读):问题三
SERIALIZABILE (可串行化):问题四
注意:
隔离级别越低可能存在的问题可能性越大;可能存在问题:
问题一:脏读 |
读取到别人尚未提交的数据 |
问题二:不可重复读 |
两次读取别人提交的数据不一致 |
问题三:幻读 |
对方提交修改数据,自己在一次事务中认为没有发生变化 |
问题三:加锁读 |
加上锁之后,其他用户无法读取 |
(2)修改隔离级别
MariaDB [(none)]> SHOWPROCESSLISTS; # 查看连接线程
注释:
tx_isolation:服务器变量,默认为REPEATABLE-READ;可在SESSION级进行修改;
MariaDB[(none)]>SETtx_isolation=''
READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE
注意:
可能会出现死锁问题:两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态;
各存储引擎自己有死锁检测和死锁超时机制,检测死锁的循环依赖发送错误通知
不能解决死锁问题会导致查询非常慢
4.事务日志文件
(1)预写式日志
事务日志帮助实现崩溃后挥发,是保证数据持久、回滚、提高事务效率的一个重要工具。
事务日志的写入类型为"追加",不是修改数据,使用的是一段连续的空间,其操作为"顺序IO",避免了写数据文件造成的大量随机IO,保证快速的将提交的操作持久存储在磁盘上,再刷写到硬盘上;该日志通常也被称为"预写式日志(writeahead logging)";
在Orcal中分为:redolog、undolog重做日志和撤销日志
(2)mysql事务日志参数
innodb_log_file_size |
日志文件大小 |
innodb_log_files_in_group |
同一组中有多少文件 |
innodb_log_group_home_dir |
一组日志文件存放的位置,/表示mysql数据的工作目录 |
innodb_log_buffer_size |
存储日志时的缓冲 |
innodb_log_block_size |
日志块的大小 |
注意:
1) 不支持运行修改,需要修改配置文件后重启;
2) 建议不要使用太大的事务日志空间,防止崩溃恢复
3) 不要混合使用不同的存储引擎,因为事务日志是不一致的
4) 崩溃后的恢复时间取决于事务日志的大小和其中所存储的事务日志的数量