“关于,是不是集群”或导入DBMS时

图片

(c)Yandex图片

所有字符都是虚构的,商标属于其所有者,任何巧合都是随机的,总的来说,这是我的“主观价值判断,请不要破门……”。

我们在将具有数据库逻辑的信息系统从一个DBMS转换到另一个DBMS方面具有丰富的经验。 在2016年11月16日第1236号政府法令中,这通常是从Oracle转移到Postgresql。 如何尽可能高效,轻松地组织流程-我们可以分别告诉您,今天我们将讨论使用集群的功能,以及在构建具有复杂逻辑和过程和功能的高负载分布式系统时可能遇到的问题。

剧透-是的,盖帽,RAC和pg multimaster是完全不同的解决方案。

假设您已经将所有逻辑从pl \ sql转移到pg \ sql。 而且您的回归测试还可以,现在您当然正在考虑缩放,因为 负载测试对您来说不是很令人满意,尤其是在该项目中,最初是在非常不同的DBMS下放置的硬件上。 假设您从国内供应商“ Postgres Professional”那里找到了一个带有“ multimaster”选件的解决方案,该解决方案仅在“ Postgres Pro Enterprise”的“最大”版本中可用,并且根据说明,它与您所需要的非常相似,并且在首次进行表面研究时就会出现我心里想:“哦! 而不是RAC! 是的,并且有了祖国的技术管道!”

但是请不要着急,我们将描述为什么您需要了解这些细微差别,因为 仔细阅读产品文档后,很难想象它们。 评估您是否准备好直接在工业站点上频繁地更新DBMS版本,如下所示 一些缺陷与工业操作不兼容,并且在测试中很难发现。
首先,请仔细阅读制造商网站上的“多主机”-“限制”部分。

您可能遇到的第一件事是交易操作的功能,即所谓的 “两阶段”模式,有时,除非通过重写过程的整个逻辑,否则无法解决。 这是一个简单的示例:

create table test1 (id integer, id1 integer); insert into test1 values (1, 1),(1, 2); ALTER TABLE test1 ADD CONSTRAINT test1_uk UNIQUE (id,id1) DEFERRABLE INITIALLY DEFERRED; update test1 set id1 = case id1 when 1 then 2 else id1 - sign(2 - 1) end where id1 between 1 and 2; 

发生错误:

 : [MTM] Transaction MTM-1-2435-10-605783555137701 (10654) is aborted on node 3. Check its log to see error details. 

然后,您可以在10.5、10.6版中长时间与死锁作斗争,并且唯一杀死集群整体本质的救恩方法是从集群中删除“问题”表,即 可以使用make_table_local,但至少可以使您工作,并且不会因为希望提交事务而“浪费”一切。 好吧,或者对版本11.2进行更新,这应该有所帮助,也可能没有帮助,请不要忘记检查。

在某些版本中,您可以获得更神秘的锁:

 username= mtm  backend_type = background worker 

在这种情况下,仅将DBMS版本更新到11.2或更高版本会有所帮助,否则可能无济于事。

在明确表明问题出在双向复制中的情况下,某些使用索引的操作可能导致错误,在MTM日志中,您将直接看到BDR。 真的是第2个象限吗? 哦,不...我们买了一个多主机,这只是一个巧合,这是技术的名称。

 [MTM] bdr doesn't support index rechecks [MTM] 12124: REMOTE begin abort transaction 4083 [MTM] 12124: send ABORT notification for transaction (5467) local xid=4083 to coordinator 3 [MTM] Receive ABORT_PREPARED logical message for transaction MTM-3-25030-83-605694076627780 from node 3 [MTM] Abort prepared transaction MTM-3-25030-83-605694076627780 status InProgress from node 3 originId=3 [MTM] MtmLogAbortLogicalMessage node=3 transaction=MTM-3-25030-83-605694076627780 lsn=9fff448 

如果您使用临时表,尽管有以下保证:“多主扩展名将以完全自动的方式复制数据。 “您可以在集群中的任何节点上同时编写事务并使用临时表。”

然后,实际上,您将获得复制不适用于该过程中使用的所有表的功能,如果代码包含创建临时表,甚至使用multimaster.remote_functions也无济于事,则您将必须更新或重写该过程中的逻辑。 如果您需要在Postgres Pro Enterprise v 10.5中同时使用两个扩展名multimaster和pg_pathman,请通过以下简单示例进行检查:

 CREATE TABLE measurement ( city_id int not null, logdate date not null, peaktemp int, unitsales int ) PARTITION BY RANGE (logdate); CREATE TABLE measurement_y2019m06 PARTITION OF measurement FOR VALUES FROM ('2019-06-01') TO ('2019-07-01'); insert into measurement values (1, to_date('27.06.2019', 'dd.mm.yyyy'), 1, 1); insert into measurement values (2, to_date('28.06.2019', 'dd.mm.yyyy'), 1, 1); insert into measurement values (3, to_date('29.06.2019', 'dd.mm.yyyy'), 1, 1); insert into measurement values (4, to_date('30.06.2019', 'dd.mm.yyyy'), 1, 1); 

在DBMS节点上的日志中开始出现以下错误:

 … PATHMAN_CONFIG doesn't contain relation 23245 > find_in_dynamic_libpath: trying "/opt/…/ent-10/lib/pg_pathman" > find_in_dynamic_libpath: trying "/opt//…/ent-10/lib/pg_pathman.so" > : find_in_dynamic_libpath: trying "/opt/…/ent-10/lib/pg_pathman" > find_in_dynamic_libpath: trying "/opt/…/ent-10/lib/pg_pathman.so" > PrepareTransaction(1) name: unnamed; blockState: PREPARE; state: INPROGR, xid/subid/cid: 6919/1/40 > StartTransaction(1) name: unnamed; blockState: DEFAULT; state: INPROGR, xid/subid/cid: 0/1/0 > switched to timeline 1 valid until 0/0 … Transaction MTM-1-13604-7-612438856339841 (6919) is aborted on node 2. Check its log to see error details. ... [MTM] 28295: REMOTE begin abort transaction 7017 … [MTM] 28295: send ABORT notification for transaction (6919) local xid=7017 to coordinator 1 

您可以在技术支持中找出这些错误是什么,这并非是您无所不包。

怎么办 对! 升级到Postgres Pro Enterprise至v 11.2

您需要单独知道,作为复制数据库的对象,它在整个集群中没有交叉值,每个序列对于每个节点都是本地的,并且如果您具有具有唯一限制的字段并使用序列,则只能在以下位置增加节点号集群,因为 集群中有多少个节点快得多,以至于序列会增长,而int的结束速度将比您预期的快。 为了简化在产品中使用序列的工作,您甚至可以找到alter_sequences函数,该函数将为所有节点上的每个序列增加必要的增量,但要准备使该函数不适用于所有版本。 当然,您可以自己编写,以github上的代码为基础,也可以直接在DBMS中更正。 同时,类型为serial \ bigserial的字段将更正确地工作,但是要使用它们,很可能需要重写过程和函数的代码。 也许有人会发现monotonic_sequences函数很有用。

在Postgres Pro Enterprise 11.2之前的版本中,复制仅在具有唯一主键的情况下才有效,在设计时请记住这一点。

我还想提到群集解决方案中npgsql的功能,这些问题不会在单个节点上发生,但是在多主服务器中却很常见。
在某些版本中,您可能会遇到错误:

 Exception Details: Npgsql.PostgresException: 25001:  SET TRANSACTION ISOLATION LEVEL Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

该怎么办? 只是不要使用某些版本。 您需要了解它们,因为 该错误不会在一个版本中出现,即使在第一次更正后,您稍后也可能会遇到。 您还需要为此做好准备,最好识别出制造商修复的所有DBMS缺陷,并用单独的回归测试进行覆盖。 可以这么说,但要信任。

如果应用程序使用npgsql并认为它们都是相同的,则在节点之间切换,那么您可能会收到错误消息:

 EXCEPTION:Npgsql.PostgresException (0x80004005): XX000: cache lookup failed for type ... 

这样的错误将由于绑定的事实而发生

 (NpgsqlConnection.GlobalTypeMapper.MapComposite<SomeType>("some_composite_type");) 

应用程序启动时所有连接的复合类型。 结果,我们从一个节点中获得了标识符,并且当在另一个节点上被请求时,它不匹配,结果返回了一个错误,即 如果没有在应用程序端进行其他重写(如果您成功做到这一点),则对于某些应用程序在集群中透明地使用复合类型将是不可能的。

众所周知,对群集状态的总体评估对于工作时的诊断和操作措施非常重要,在产品中您可以找到一些使您的生活更轻松的功能,但有时它们可​​能根本无法产生您甚至制造商自己期待。

例如:

 select mtm.collect_cluster_info();      : (1,Online,0,0,0,2,3,0,0,0,1,0,0,1,1,3,7,0,0,0,"2018-10-31 05:33:06") (2,Online,0,0,0,2,3,0,0,0,1,0,0,1,1,3,7,0,0,0,"2018-10-31 05:33:06") (3,Online,0,0,0,2,3,0,0,0,1,0,0,1,1,3,7,0,0,0,"2018-10-31 05:33:09") 

但是,为什么在LiveNodes字段中到处都是数字2,尽管根据多主机工作的描述,它应该对应于数字AllNodes = 3? 答:您需要更新DBMS版本。

并准备收集所有节点上的日志,如下 通常您会看到“错误出在另一个节点的日志中”。 TechSupport将接受所有已发现的缺陷,并通知您下一个版本已准备就绪,有时将需要在停止服务的情况下进行安装,有时需要长时间(取决于DBMS的容量)。 不值得期望的是,操作问题将极大地干扰供应商,并且由于已识别出的缺陷而导致的更新将在供应商代表的参与下进行,或者更确切地说,甚至没有必要让供应商代表参与,因为最终您可以获得拆卸后的群集而无需在产品上进行备份。

实际上,在商业产品的许可证中,制造商会诚实地警告:“此软件是按“原样”提供的,不需要Postgres Professional有限责任公司提供支持,支持,更新,扩展或更改。

如果您还没有猜到我们在谈论哪种产品,那么Postgres Pro Enterprise基地的年度运营将为您带来所有这些经验。 您可以自己得出结论,如蘑菇般潮湿。

但是,如果及时进行并及时消除出现的问题,那将是麻烦的一半。

但这只是没有发生。 显然,制造商的资源不足以快速修复已发现的错误。

Source: https://habr.com/ru/post/zh-CN481302/


All Articles