MariaDB数据库并发控制和日志管理

---------------------------------------------------------------------------------------------------------------------------------------------

1、并发控制

    (1)锁粒度:表级锁、行级锁

    (2)读锁:共享锁,只读不可写,多个读取互不阻塞,意思是多台主机可以同时查看一张上了读锁的表

        写锁:独占锁、排它锁,一个写锁会阻塞其它读和写锁,当A用户对表上写锁,其他用户对该表不能读,更不能写

    (3)使用锁

        LOCK TABLES tblname {READ | WRITE}:加锁

  UNLOCK TABLES:解锁

  FLUSH TABLES TBNAME:关闭正在打开的表,在备份前加全局读锁,如果不指定表明,全部数据库全部表格都将加入读锁,适用于温备分

  SELECT...WHERE从句 FOR UPDATE:加写锁

  SELECT...WHERE从句  LOCK IN SHARE MODE:加读锁

读锁示例

写锁示例

    (4)实现

存储引擎:自行实现其锁策略和锁粒度

服务器级:实现了锁,表级锁;用户可显示请求

    (5)分类

隐式锁:由存储引擎自动施加锁

显示锁:用户手动请求

    (6)锁策略:在锁粒度及数据安全性寻求的平衡机制

2、事务

    (1)事务Transactions:一组原子性的SQL语句,或一个独立动作单元

    (2)事务日志:记录事务信息,实现undo,redo等故障恢复功能

    (3)事务的ACID特性:

A:atomicity,原子性,整个事务中的所有操作要么全部成功执行,要么全部失败后回滚

C:consistency一致性,数据库总是从一个一致性状态转换为另一个一致性状态

I:isolation隔离性,一个事务所做出的操作在提交之前,不能被其它事务所见,隔离有多种隔离级别,实现并发

D:durability持久性,一旦事务提交,其所做的修改会永久保存于数据库中

3、事务生命周期

4、事务流程

(1)启动事务

BEGIN、BEGIN WORK\START TRANSACTION

(2)结束事务

COMMIT:提交,ROLLBACK:回滚

注:只有事务型存储引擎中的DML语句方能支持此类操作,即增删改操作

(3)自动提交:set autocommit={1|0},默认为1,为0时设为手动提交

建议:显式请求和提交事务,而不要使用“自动提交”功能

mysql和sql server默认设置是自动提交,oracle默认手动提交

网站查询结果是--autocommitautocommit表明选项和变量都有

(4)事务支持保存点:savepoint

SAVEPOINT identifier

ROLLBACK [WORK] TO [SAVEPOINT] identifier

RELEASE SAVEPOINT identifier

注意:savepoint保存点名称必须字母开头,不可以是纯数字

示例

提交后

事务保存点示例:先有以下结果产生

此时后悔了,想把数据表恢复到savepoint sp2处,也就是sp2点完菜,但未做sp3点,结果如图

5、事务隔离级别

(1)事务隔离级别:从上到下越来越严格

<1>READ UNCOMMITTED 可读取到未提交数据,产生脏读

<2>READ COMMITTED 可读取到提交数据,但未提交数据不可读,产生不可重复读,即可读取到多个提交数据,导致每次读取数据不一致

<3>REPEATABLE READ 可重复读,多次读取数据都一致,产生幻读,即读取过程中,即使有其它提交的事务修改数据,仍只能读取到未修改前的旧数据。此为MySQL默认设置,意思是修改记录过程中表格对其他用户产生行锁,事务完成提交后才对其他用户显示修改后的数据

<4>SERIALIZABILE 可串行化,未提交的读事务阻塞修改事务,或者未提交的修改事务阻塞读事务。导致并发性能差

(2)MVCC: 多版本并发控制,和事务级别相关

事务隔离级别

脏读可能性

不可重复读

可能性

幻读可能性

加锁读

读未提交(read-uncommitted)

Y

Y

Y

N

不可重复读(read-committed)

N

Y

Y

N

可重复读(repeatable-read)

N

N

Y

N

串行化(serializable)

N

N

N

Y

(3)指定事务隔离级别

SET tx_isolation=''

READ-UNCOMMITTED

READ-COMMITTED

REPEATABLE-READ

SERIALIZABLE

服务器选项中指定

vim /etc/my.cnf

[mysqld]

transaction-isolation=SERIALIZABLE

6、并发控制

    (1)死锁:两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态

    (2)事务日志的写入类型为“追加”,因此其操作为“顺序IO”;通常也被称为:预写式日志 write ahead logging,条件允许可以将事务日志独立放入一个硬盘分区中,使得事务日志的写入不用随便插入地方进行写入而是追加

    日志文件: ib_logfile0, ib_logfile1,位于数据库存放目录下,可以更

7、解决阻塞(工作中慎用)

    (1)show processlist \G

    (2)看到数据库进程后确定结束阻塞的id号,比如5号,输入kill 5

8、日志

    (1)当对一个表格删除大量数据后,它的日志文件不会缩小,此时需要优化表格,执行命令:optimize table TBLNAME,使得该表的日志文件容量缩小

    (2)日志类型

        <1>日志

 附:慢查询profiling工具用法

        <2>二进制日志,因为非常重要,内容又多,所以单独放一分类

        <3>二进制日志的客户端命令工具

mysqlbinlog [OPTIONS] log_file...

--start-position= 指定开始位置的POS点

--stop-position= 指定结束位置的POS点

--start-datetime=

--stop-datetime=

时间格式,YYYY-MM-DD hh:mm:ss

--base64-output[=name]

示例:mysqlbinlog --start-position=1465 --stop-position=2123 mysql-bin.000001

        <4>清除指定二进制日志

            PURGE { BINARY | MASTER } LOGS

{ TO 'log_name' | BEFORE datetime_expr }

示例:

PURGE BINARY LOGS TO ‘mariadb-bin.000003’;删除3之前的日志

PURGE BINARY LOGS BEFORE '2017-01-23';

PURGE BINARY LOGS BEFORE '2017-03-22 09:25:30';

        <5>删除所有二进制日志,index文件重新记数

RESET MASTER [TO #]; 日志文件从#开始记数,默认从1开始,一般是master第一次启动时执行,MariaDB10.1.6开始支持TO #

        <6>切换日志文件:

FLUSH LOGS;