一大卖点的Postgre数据库是
处理并发的方式。我们的期望很简单:读不块,反之亦然。Postgres已经通过一个称为多版本并发
控制(MVCC)。这种技术不仅是Postgres:有几个数据库,实现了不同形式的MVCC,包括甲骨文、伯克利DB,CouchDB等等。当你使用PostgreSQL设计一个高并发的应用中,重要的是要明白如何MVCC实现。是的,事实上,一个非常优雅和简单的
解决复杂的问题。
怎么个
工作 在Postgres,每一笔交易会交易称为xid,事务ID的交易在这里不仅是一组语句包裹开始提交,但也是一个单一的插入,更新,或
删除表。当事务开始时,postgrel增量的xid然后将其分配到Postgres也存储交易。交易相关信息在
系统中的每一行,这是用来确定是否一行可以记录当前事务可见。
例如,当你插入一行记录,Postgre商店在这条线的当前事务XID叫xmin。只记录已被提交和xmin `小于当前事务码是当前事务可见。这意味着你可以开始一个新的交易和插入一行记录。直到你提交(COMMIT),记录你插入的其他事务可见不。提交时,其他新的交易
创建后就能看到该行的新纪录,因为他们满足xmin < XID
条件和交易这行的记录已完成。
删除和更新,机制是相似的,但这是他们的Postgres使用值称为重新确定数据的可见性不同。这张
照片显示了MVCC工作事务隔离两
并行插入/读取数据的事务。
在下面的图表中,假设我们首先
执行了这个语句:
复制代码代码如下:创建表编号(值int);
虽然xmin和xmax的价值是隐藏在日常使用中,你可以直接问他们,和Postgres会很乐意给你的价值。
复制代码代码如下:SELECT *,xmin,Xmax的号码;
获得当前事务码也很简单:
复制代码代码如下:选择txid_current();
光滑、清洁、uff01
我知道你现在在想:如果有两个事务同时
修改同一行数据呢这是当时的事务隔离级别是在舞台上。Postgres
支持两种基本的
模式让你控制你应该如何处理这种
情况。
默认情况下,读提交(提交读)是用来
等待被完成的初始交易然后读取线记录和执行的语句。如果修改记录时等待的过程中,它会从头再来。例如,当你
运行一个更新与WHERE子句,子句将初始交易后返回的命中结果提交。如果满足WHERE子句的条件,则将执行更新。在下面的示例中,两个事务同时修改同一行记录。初始更新语句会导致第二个事务的
位置不返回任何记录,因此第二个事务根本不会修改到任何记录。
如果你需要更好地控制这种行为,你可以
设置事务隔离级别为可序列化(序列化)。在这种
策略中,上述情况将直接因为未能遵循这样的规则:如果我修改由其他事务修改的话,不要在同一时间,Postgres将返回此
错误信息:由于并发修改会导致串行访问。捕获这个错误并再次尝试你的
应用程序需要做什么,或者不想放弃,如果它是合理的。
MVCC的缺点
现在你知道MVCC和事务隔离工作,你得到一个新的
工具来解决这个问题:可序列化事务隔离级别将派上用场。然而,尽管MVCC的优点是显而易见的,它也有一些缺点。
因为不同的交易,会看到一个不同的状态记录,Postgres也需要保持,可能是过期的数据。这就是为什么更新实际上是创造新的一行记录。删除不删除记录(这仅仅是记录的删除和套码值),当交易完成后,在数据库中,将不会对未来的交易明显有一些记录。他们被称为死行。另一个问题是,MVCC带来交易的ID只能增加-这是32位的,只能支持四十亿交易。当XID达到最大,回零,重新
启动。一下子全部记录在未来产生的,和所有新的交易不到旧记录访问。
死行和交易XID环以上问题
都是通过执行
命令解决真空(postgres是用来执行
清理操作的命令)。这应该是一个日常的保养,所以Postgre以auto_vacuum后台自动执行清理在一个可
配置的周期。这是关注点auto_vacuum重要的,因为这需要在不同的部署环境的清洁周期是不同的,你可以找到在Postgres真空更说明
文档。