相关 Document

1. 事务基本概念:

  1. 1. 原子性:
  2. 一个事务的所有操作,要么全部执行,要么全部不执行。
  3. 2. 一致性:
  4. 执行事务时保持数据库从一个一致的状态变更到另一个一致的状态。
  5. 3. 隔离性:
  6. 即使每个事务都能确保一致性和原子性,如果并发执行时,由于它们的操作以人们不希望的方式交叉运行,就会导致不一致的情况发生。确保事务与事务并发执行时,每个事务都感觉不到有其它事务在并发的执行。

2. 四种隔离级别:

隔离级别 脏读 不可重复读 幻读 序列化异常
read uncommitted 不可能 可能 可能 可能
read committed 不可能 可能 可能 可能
repeatable read 不可能 不可能 不可能 可能
serializable 不可能 不可能 不可能 不可能

2.1 查看和设置数据库的事务隔离级别:

  1. # 查看全局事务隔离级别:
  2. select name,setting from pg_settings where name='default_transaction_isolation';
  3. # 修改全局事务隔离级别:
  4. 方法一:修改postgresql.conf配置文件中的default_transaction_isolation
  5. 方法二:
  6. alter system set default_transaction_isolation to 'repeatable read';
  7. pg_ctl reload
  8. # 查看当前会话的事务隔离级别:
  9. show transaction_isolation;
  10. # 设置当前会话的事务隔离级别:
  11. set session characteristics as transaction isolation level read uncommitted;
  12. # 设置当前事务的隔离级别:
  13. begin isolation level read uncommitted read write;
  14. commit;

3. 并发问题模拟

3.1 脏读问题: 🤷‍♂️

PG中不存在未提交读隔离级别,显示使用未提交读隔离级别时,PG内部会使用为提交读隔离级别处理,脏读在PG中不会发生。

  1. # 脏读演示:(PG数据无法演示脏读,请用其它数据库)
  2. create table tb1_mvcc (id serial not null primary key,ival int);
  3. insert into tb1_mvcc (ival) values (1);
  4. 会话一:
  5. set session transaction isolation level read uncommitted;
  6. begin;
  7. 会话二:
  8. set session transaction isolation level read uncommitted;
  9. begin;
  10. update tb1_mvcc set ival=10 where id=1;
  11. 会话一:
  12. select * from tb1_mvcc where id=1;
  13. 会话二:
  14. rollback;

3.2 不可重复读问题:

  1. # 不可重复读:
  2. 会话一:
  3. begin transaction isolation level read committed;
  4. 会话二:
  5. begin;
  6. update tb1_mvcc set ival=10 where id=1;
  7. commit;
  8. 会话一:
  9. select * from tb1_mvcc where id=1;
  10. end;

3.3 幻读问题:

  1. # 幻读
  2. create table tb1_mvcc (id serial not null primary key,ival int);
  3. insert into tb1_mvcc (ival) select generate_series(1,5);
  4. 会话一:
  5. begin transaction isolation level read committed;
  6. select id,ival from tb1_mvcc where id>3 and id<10;
  7. 会话二:
  8. begin;
  9. insert into tb1_mvcc (ival) values (6);
  10. commit;
  11. 会话一:
  12. select id,ival from tb1_mvcc where id>3 and id<10;
  13. end;

3.4 序列化一场问题:

  1. # 序列化异常:
  2. create table tb1_mvcc (id serial not null primary key,ival int);
  3. insert into tb1_mvcc (ival) values (1);
  4. 会话一:
  5. begin transaction isolation level repeatable read;
  6. select * from tb1_mvcc where id=1;
  7. 会话二:
  8. update tb1_mvcc set ival=10 where id=1;
  9. 会话一:
  10. update tb1_mvcc set ival= ival+1 where id=1;
  11. rollback;
  12. # 不可能出现幻读:
  13. create table tb1_mvcc (id serial not null primary key,ival int);
  14. insert into tb1_mvcc (ival) select generate_series(1,5);
  15. 会话一:
  16. begin transaction isolation level repeatable read;
  17. select id,ival from tb1_mvcc where id>3 and id<10;
  18. 会话二:
  19. begin;
  20. insert into tb1_mvcc (ival) values (6);
  21. commit;
  22. 会话一:
  23. select id,ival from tb1_mvcc where id>3 and id<10;
  24. end;

4. 使用pg_repack解决表膨胀:

  1. # 安装pg_repack工具:
  2. ## yum安装:(yum安装的repack只能针对yum安装的pg)
  3. yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
  4. yum install pg_repack13 -y
  5. vi /etc/profile
  6. export PATH=/usr/pgsql-13/bin:$PATH
  7. ## 源码安装:
  8. yum install gcc postgresql-devel postgresql-static zlib-devel readline-devel -y
  9. unzip pg_repack-master.zip
  10. cd pg_repack-master
  11. make && make install
  12. pg_repack --version
  13. # 创建pg_repack扩展:
  14. create extension pg_repack;
  15. # 进行对表进行重建:
  16. pg_repack -t t1 -j 2 -D -k -U postgres -d postgres

表膨胀原因及处理:案例 分析

  1. 1. 表膨胀的直接触发因素是表上的大量更新,如全表的update操作、大量的insert+delete操作等
  2. 2. 一个update操作执行后,被更改的数据的旧版本也被保留下来,直到对表做vacuum操作的时候,才考虑回收旧版本。
  3. 3. 旧版本不及时回收就会造成表膨胀

特点:

  1. 1. 更新过数据的事务,长时间不提交会造成表膨胀,只读的事务也是同样的,也要及时提交,同时避免在存在大量更新操作的实例上,跑运行时间很长的查询语句。

避免表膨胀的方法:

  1. 1. 尽早的、及时的提交事务;
  2. 2. 设计应用时,要使事务尽量短小;
  3. 3. 注意配置与应用规模相适应的硬件资源(IO能力、CPU、内存等),并调教好数据库,使其性能最优,避免有些事务因为资源或性能问题长时间无法完成;
  4. 4. 提交autovacuum,使其能按合理的周期运行。这方面的内容,我们今后专门介绍;
  5. 5. 定期监控系统中是否有长事务,可以使用下面的SQL监控持续时间超过一定时间的事务

image.png

image.png