HashData 数据库的并发控制
HashData 数据库使用 PostgreSQL 多流并发控制( MVCC )模型来管理堆表的并发事务。
数据库管理系统中的并发控制允许并发查询在确保数据库的完整性的同时得到正确的结果。传统数据库使用两阶段锁定协议,阻止事务修改已被另一个并发事务读取的数据,并阻止任何并发事务读取或写入另一个事务已更新的数据。协调事务所需的锁将增加对数据库的争用,从而降低总体事务吞吐量。
HashData 数据库使用 PostgreSQL 多流并发控制( MVCC )模型来管理堆表的并发性。使用 MVCC ,当查询开始时,每个查询都会对数据库的快照进行操作。执行时,查询不能看到其他并发事务所做的更改。这样可以确保查询查看数据库的一致视图。读取行的查询永远不会阻止等待写入行的事务。相反,写入行的查询不能被读取行的事务阻止。与传统的数据库系统相比,这种数据库系统可以实现更大的并发性,这些数据库系统使用锁来协调读写数据的事务间的访问。
注意:使用与本主题中讨论的 MVCC 模型不同的并发控制模型管理 Append-optimized 表。它们适用于“一次写入,多读”的应用程序,这些应用程序不会执行或很少执行行级更新。
快照
MVCC 模型取决于系统管理多个版本的数据行的能力。在查询开始时,查询对数据库的快照进行操作。快照是在语句或事务开头可见的行集合。该快照确保在执行期间查询具有一致且有效的数据库视图。
每个事务被分配一个唯一的 事务ID(XID),一个递增的 32 位值。当一个新事务开始时,它被分配下一个 XID 。未包含在事务中的 SQL 语句被视为单语句事务开始和承诺被隐含地添加。这与某些数据库系统中的自动提交类似。
当事务插入一行时, XID 将保存在该行中 XMIN 系统列。当事务删除一行时, XID 将保存在 XMAX 系统列。更新行被视为删除和插入,因此 XID 保存到 XMAX 的当前行和 XMIN 的新插入行。该 XMIN 和 XMAX 列与事务完成状态一起指定行的版本可见的事务范围。一个交易可以看到所有交易的影响小于XMIN,它们被保证被承诺,但是它看不到任何大于或等于的事务的影响XMAX。
多语句事务还必须记录一个事务中的哪个命令插入一行(的Cmin)或删除一行(的Cmax),以便事务可以看到事务中先前命令所做的更改。命令序列仅在事务期间相关,因此在事务开始时,序列将重置为0。
XID是数据库的一个属性。每个段数据库都有自己的XID序列,无法与其他段数据库的XID进行比较。主人使用群集范围的会话ID号来协调与段的分布式事务,称为gp_session_id。分段维护分布式事务ID与其本地XID的映射。主人通过两阶段提交协议来协调跨所有段的分布式事务。如果任何一个分段上的事务失败,它将在所有分段上回滚。
你可以看到
XMIN
,
XMAX
,
的Cmin
,和
的Cmax
用于任何行的列
选择
声明:
SELECT xmin,xmax,cmin,cmax,* FROM
tablename
;
因为你跑了选择主机上的命令,XID是分布式事务ID。如果您可以在单个段数据库中执行该命令XMIN和XMAX值将是段的本地XID。
事务ID包装
MVCC模型使用事务ID(XID)来确定哪些行在查询或事务的开始处可见。XID是一个32位的值,因此数据库理论上可以在值溢出之前执行超过40亿次事务,并将其转换为零。然而,Greenplum数据库使用XIDs的模32运算,这允许事务ID循环,就像十二点钟一样。对于任何给定的XID,可能有大约20亿的XID和20亿未来的XID。这样一来,直到一个版本的版本依然存在着大约20亿次的交易,当它突然出现在新的一行。为了防止这种情况,Greenplum有一个特殊的XID,叫做为FrozenXID,它总是被认为比任何常规XID比较更老。该XMIN的一行必须被替换为FrozenXID在20亿笔交易中,这是其中的一个功能真空命令执行。
至少每隔二十亿次事务就可以避免使用数据库来防止XID环绕。Greenplum数据库监控事务ID,并发出警告真空需要操作。
当交易ID的很大一部分不再可用并且事务ID环绕发生之前会发出警告:
警告:数据库“
database_name
”必须在
number_of_transactions
事务中
抽真空
当发出警告时,a真空需要操作。如果一个真空不执行操作,Greenplum数据库将停止创建事务,以避免在事务ID环绕发生之前到达限制时可能的数据丢失,并发出此错误:
FATAL:数据库不接受命令以避免数据库“
database_name
”中的
环绕数据丢失
请参阅从事务ID限制恢复限制从此错误中恢复的过程的错误。
服务器配置参数xid_warn_limit和xid_stop_limit控制何时显示警告和错误。该xid_warn_limit参数指定之前的事务ID数xid_stop_limit当警告发出时。该xid_stop_limit参数指定发生错误并且无法创建新事务之前发生环绕的事务ID数。
事务隔离模式
SQL标准描述了数据库事务同时运行时可能会发生的三种现象:
- 脏读
- 一个事务可以从另一个并发事务读取未提交的数据。
- 不可重复读取
- 在事务中读取两次的行可能会改变,因为在事务开始之后,另一个并发事务已更改。
- Phantom读取
- 在同一事务中执行两次的查询可以返回两组不同的行,因为另一个并发事务添加了行。
SQL标准定义了数据库系统必须支持的四种事务隔离模式:
水平 | 脏读 | 不可重复 | 幻影阅读 |
阅读未提交 | 可能 | 可能 | 可能 |
阅读承诺 | 不可能 | 可能 | 可能 |
可重复阅读 | 不可能 | 不可能 | 可能 |
序列化 | 不可能 | 不可能 | 不可能 |
Greenplum Database SQL命令允许您进行请求阅读未经通知,阅读承诺, 要么SERIALIZABLE。Greenplum数据库处理阅读未经通知一样阅读承诺。请求重复阅读产生错误;使用SERIALIZABLE代替。默认隔离模式为阅读承诺。
和...之间的不同阅读承诺和SERIALIZABLE是在阅读承诺模式下,事务中的每个语句只能在语句启动之前看到所提交的行,而在SERIALIZABLE模式下,事务中的所有语句只能在事务开始之前查看提交的行。
该阅读承诺隔离模式允许更大的并发性和更好的性能SERIALIZABLE模式。它允许不可重复的读取,其中在事务中检索两次的行中的值可能会有所不同,因为另一个并发事务自事务开始以来已经提交更改。阅读承诺模式还允许幻影读取,其中在同一事务中执行两次的查询可以返回两组不同的行。
该SERIALIZABLE隔离模式防止不可重复的读取和幻像读取,但是以并发和性能为代价。每个并发事务在执行开始时都具有一致的视图。尝试修改由另一个事务修改的数据的并发事务被回滚。执行交易的应用程序SERIALIZABLE必须准备模式来处理由于序列化错误而失败的事务。如果SERIALIZABLE应用程序不需要隔离模式,最好使用阅读承诺模式。
SQL标准规定,并发可序列化事务会产生与依次执行的数据库状态相同的数据库状态。MVCC快照隔离模型可防止脏读,不可重复的读取和幻像读取,而不需要昂贵的锁定,但还有一些其他交互可能发生在某些SERIALIZABLEGreenplum数据库中的交易阻止了它们的真正可序列化。这些异常通常可归因于Greenplum数据库不执行谓词锁定,这意味着在一个事务中的写入可能会影响先前在另一个并发事务中的读取结果。
应检查并发运行的事务,以确定通过不允许同时更新同一数据而阻止的交互。可以通过使用显式表锁或通过要求冲突的事务来更新引入以表示冲突的虚拟行来防止所识别的问题。
SQL
设置交易隔离水平
语句设置当前事务的隔离模式。
模式必须先设置
选择
,
插
,
删除
,
UPDATE
, 要么
复制
声明:
开始;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
...
承诺;
隔离模式也可以指定为
开始
声明:
开始交易隔离级别可串行;
可以通过设置default_transaction_isolation配置属性来更改会话的默认事务隔离模式。
从表中删除死排
更新或删除行将在表中留下该行的过期版本。当任何活动事务不再引用过期的行时,它可以被删除,并且它占用的空间可以重复使用。该真空命令从表中删除过期的行。
当过期行累积在表中时,必须扩展磁盘文件以适应新行。由于执行查询所需的磁盘I / O增加,性能受损。这种情况称为膨胀,它应该通过定期抽真空的桌子进行管理。
该真空命令(没有充分)可以与其他查询同时运行。它从页面中删除过期的行,并重新排列剩余的行以合并可用空间。如果剩余可用空间的数量很大,它会将页面添加到表的可用空间映射。当Greenplum数据库稍后需要新行的空间时,它首先查阅表的可用空间映射来查找具有可用空间的页面。如果没有找到,新的页面将被附加到该文件。
真空(不充分)不合并页面或减小磁盘上的表的大小。它恢复的空间只能通过自由空间地图获得。为了防止磁盘文件的增长,重要的是运行真空通常,每天至少要一次,以确保通过自由空间地图找到可用空间。运行也很重要真空在运行更新或删除大量行的事务之后。
该真空满命令重写表而不过期行,将表缩小到最小大小。必须有足够的磁盘空间来创建新表,并且表被锁定直到真空满完成。这是非常昂贵的比较常规真空命令,并可以避免或推迟定期抽真空。最好跑真空满在维护期间。一个替代真空满是用a重新创建表创建表AS声明然后放弃旧表。
可用空间映射位于共享内存中,并跟踪所有表和索引的可用空间。每个表或索引使用大约60字节的内存,每个具有可用空间的页面消耗六个字节。两个系统配置参数配置自由空间映射的大小:
max_fsm_pages
设置可以添加到共享可用空间映射的最大磁盘页数。
每个页面槽都占用了六个字节的共享内存。
默认值为200000.此参数必须设置为
max_fsm_relations
值的至少16倍
。
max_fsm_relations
设置共享内存空间映射中将要跟踪的最大关系数。该参数应设置为大于表+索引+系统表的总数的值。默认值为1000.每个段实例的每个关系消耗大约60个字节的内存。最好将参数设置得太高太低。
如果可用空间映射不正确,则有一些可用空间的磁盘页面将不会添加到映射中,并且至少在下一个真空命令运行。这会导致文件增长。
你可以跑VACUUM VERBOSEtablename通过分段获取已删除的死排数,受影响的页数以及可用空间的页数。
查询
pg_class里
系统表,以查找表在所有段中使用的页数。
务必
分析
表首先得到准确的数据。
SELECT relname,relpages,reltuple FROM pg_class WHERE relname ='
tablename
';
另一个有用的工具是gp_bloat_diag查看在gp_toolkit模式,通过将表使用的实际页数与预期数量进行比较来识别表中的膨胀。请参阅在“The gp_toolkit管理模式”的Greenplum数据库参考指南的更多信息gp_bloat_diag。
父主题:Greenplum数据库概念