MySQL优化-MySQL事务
时间:2020-04-12
本文章向大家介绍MySQL优化-MySQL事务,主要包括MySQL优化-MySQL事务使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
MySQL优化-MySQL事务 事务(transaction)是一组SQL组成的执行单元(unit),是数据库并发控制和恢复回滚的基本单位。 一个事务可能包含多个SQL,要么都失败,要么都成功。 事务具备4个基本属性:ACID Atomic,同一个事务里,要么都提交,要么都回滚。 Consistency,即在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。 Isolation,并发事务间的数据是彼此隔离的。 Durability,事务提交后,所有结果务必被持久化。 支持事务的引擎:InnoDB、NDBCluster、TokuDB、RocksDB。 不支持事务的引擎:MyISAM、MEMORY/HEAP。 [dba@localhost:mysql.sock] [(none)]> show engines; +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | Engine | Support | Comment | Transactions | XA | Savepoints | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO | | CSV | YES | CSV storage engine | NO | NO | NO | | MyISAM | YES | MyISAM storage engine | NO | NO | NO | | BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO | | PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO | | InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES | | ARCHIVE | YES | Archive storage engine | NO | NO | NO | | MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO | | FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ 9 rows in set (0.00 sec) 显式开始事务 start transaction; read write with consistent snapshot read only -- 默认 begin;/begin work; 关闭自动提交 set autocommit | @@autocommit = 0 提交事物 1.显式提交 commit; 2.隐式提交 begin/begin work start transaction set autocommit = 1 其他非事务语句DDL/DCL 回滚事务 1.显式回滚 rollback; 2.隐式回滚 连接断开,mysql> exit; 超时断开,mysql> timeout; 被kill,mysql> kill xxx; 异常宕机。 目前还不支持嵌套事务。 DCL、DDL也不支持事务,因此在事务中也不要执行这些。 autocommit = 0 必要吗? 好处:多语句提交时,不会每个SQL单独提交,提高事务提交效率。 麻烦: 有个事务忘记提交,锁一直未释放。 另一个事务长期锁等待,严重影响TPS。 尽量不要设置autocommit = 0 Python中的autocommit。 import MySQLdb 或者 import pymysql from time import sleep conn = MySQLdb.connect(user='dev',password='123',host='10.0.0.11',port=3306,) # conn.autocommit = True (这是不对的) cur.execute("set autocommit=1;") 或者 cur.autocommit(1) cur = conn.cursor() cur.execute("show global status;") while 1: sleep(1) 如果没有事务控制的话,那么并发读写数据库会有什么隐患? 脏读: 事务T1修改了一行数据,事务T2在事务T1提交之前读到了该行数据。 不可重复读 事务T1读取了一行数据,事务T2接着修改或者删除了该行数据,当T1再次读取同一行数据的时候,读到的数据是修改之后的或者发现已经被删除了。 幻读: 事务T1读取了满足某条件的一个数据集,事务T2插入了一行或者多行数据满足了T1的选择条件,导致事务T1再次使用同样的选择条件读取的时候,得到了比第一次读取更多的数据集。 事务隔离级别 RU(读未提交)隔离级别最低。 允许脏读,允许事务查看其它事务所进行的未提交的更改。 RC(读已提交) 允许幻读,允许事务查看其它事务所进行的已提交更改。 RR(可重复读) 消除了脏读、不可重复读、幻读、保证事务一致性,确保每个事务的读取结果总是一样,默认隔离级别。 SR(串行)隔离级别最高 串行化读,每次读都需要获得表级共享锁,读写间相互都会阻塞。 my.cnf配置 [mysqld] transaction-isolation = "READ-COMMITTED" 默认是REPEATABLE-READ,不确定时,就用默认的RR级别。 在线全局修改 set global transaction isolation level read committed; 查看当前隔离级别 [dba@localhost:mysql.sock] [(none)]> select @@global.tx_isolation,@@session.tx_isolation,@@transaction_isolation; +-----------------------+------------------------+-------------------------+ | @@global.tx_isolation | @@session.tx_isolation | @@transaction_isolation | +-----------------------+------------------------+-------------------------+ | REPEATABLE-READ | REPEATABLE-READ | REPEATABLE-READ | +-----------------------+------------------------+-------------------------+ 1 row in set, 2 warnings (0.00 sec) 快照读,snapshot read 基于read view读可见版本,不加锁。 start transaction with consistent read + select 普通select 快照,read view 由基于某个时间点的一组InnoDB内部(活跃)事务构建而成的列表。 当前读,current read 读(已提交)最新版本,并加锁。 S锁,select ... share/lock in share mode X锁,select ... for update/DML 加 for update 是当前读,排它锁。 大部分情况下,其实选择RC隔离级别就可以,例如常规的游戏、微博、社区、社交等业务场景中。 Oracle和SQL Server默认隔离级别也是RC。 在金融、交易类业务场景中,一方面在业务上要做好数据完整性、一致性判断,在数据库层面,最好也选择RR隔离级别,进一步保障数据可靠性。 InnoDB只读事务 5.6开始支持。 5.7进一步优化,不记录redo log。 5.7起,非显式声明的事务,默认都是以只读模式启动,事务过程中有数据被修改时,才自动变更为读写模式。 显式声明的只读事务是 innodb_trx.trx_is_read_only = 1 innodb_flush_log_at_trx_commit = 1 sync_binlog = 1 所谓的双1,用于保证数据的持久性。 kill -9 mysqld_pid,如果设置了双1参数是不会出现坏页的。 这种情况下如果出现磁盘坏页,有两种情况: 1.MySQL的bug。 2.硬件问题导致。 如果出现坏页,就直接去想把数据尽快恢复出来,不用想其它的了。 InnoDB是如何利用独特的gap lock机制来解决幻读? RR级别下解决了幻读问题。 引入gap lock,把2条记录中间的gap锁住,避免其他事务写入。 存在幻读的条件。 <= RC级别。 innodb_locks_unsafe_for_binlog = 1(8.0之后废弃该选项) 什么是半一致性读 InnoDB semi-consistent read semi-consistent read是read committed与consistend read的结合。 update语句如果读到一行已经加锁的记录,此时InnoDB返回该记录(已提交的)最新版本,并再次判断此版本是否满足update的where条件。 若满足(需要更新),则会重新发起一次读操作,此时会读取行的最新版本,并加锁。 semi-consistent read发生的条件。 <= read committed隔离级别。 innodb_locks_unsafe_for_binlog = 1 时(8.0之后废弃该选项) update请求(不含insert、delete) 本节小结: InnoDB特有的半一致性读,是为了提高没索引时的update效率。
原文地址:https://www.cnblogs.com/zhouwanchun/p/12687541.html
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解