ManualQueryPropagation当用户发出查询时,Citus协调器将其分成更小的查询片段,其中每个查询片段可以在工作分片上独立运行。这允许Citus跨集群分发每个查询。但是,查询分为片段的方式(以及传播哪些查询)因查询类型而异。在某些高级情况下,手动控制此行为很有用。Citus提供实用程序功能来将SQL传播到工作程序、分片或位置。手动查询传播绕过协调器逻辑、锁定和任何其他一致性检查。这些函数可以用作最后的手段来允许Citus不会以其他方式本地运行的语句。小心使用它们以避免数据不一致和死锁。在所有worker上运行的最小执行级别是广播要在所有worker上执行的语句。这对于查看整个工作数据库的属性很有用。--列出每个worker数据库的work_mem设置SELECTrun_command_on_workers($cmd$SHOWwork_mem;$cmd$);注意:此命令不应用于在工作节点上创建数据库对象,因为这样做会使自动添加工作节点变得更加困难。注意:本节中的run_command_on_workers函数和其他手动传播命令只能运行返回单列单行的查询。在所有分片上运行下一个粒度级别是在特定分布式表的所有分片上运行命令。例如,当直接在worker上读取表的属性时,它可能很有用。在工作节点上本地运行的查询可以完全访问元数据,例如表统计信息。run_command_on_shards函数将SQL命令应用于每个分片,为命令中的插值提供分片名称。下面是一个通过使用每个worker上的pg_class表来估计每个分片的行数来估计分布式表中行数的示例。请注意将替换为每个分片名称的%s。--通过对每个分片的估计行数求和来获取分布式表的估计行数。SELECTsum(result::bigint)ASestimated_countFROMrun_command_on_shards('my_distributed_table',$cmd$从pg_classcJOINpg_catalog.pg_namespacenonn.oid=c.relnamespaceWHERE(n.nspname||'.'||relname::regclass='%s'::regclassANDn.nspnameNOTIN('citus','pg_toast','pg_catalog')$cmd$);在所有puts上运行最细粒度的执行级别是在所有分片及其副本(akaputs)上运行命令。它对于运行必须应用于每个副本以确保一致性的数据修改命令很有用。例如,假设分布式表有一个updated_at字段,我们想“接触”所有行,以便在某个时候将它们标记为已更新。协调器上的普通UPDATE语句需要按分布列进行过滤,但我们可以手动将更新传播到所有分片和副本:——注意我们使用的是硬编码日期,而不是——诸如“now”之类的函数()”,因为查询将--在每个replicaSELECTrun_command_on_placements('my_distributed_table',$cmd$UPDATE%sSETupdated_at='2017-01-01';$cmd$)上运行的时间略有不同;run_command_on_placements的一个有用伙伴是run_command_on_colocated_placements。它将位于同一位置的分布式表中两个位置的名称插入到查询中。始终选择放置对作为与本地相同的工作器,其中可以使用完整的SQL覆盖率。因此,我们可以使用触发器等高级SQL功能来关联表:--假设我们有两个分布式表CREATETABLElittle_vals(keyint,valint);CREATETABLEbig_vals(keyint,valint);SELECTcreate_distributed_table('little_vals','key');SELECTcreate_distributed_table('big_vals','key');--我们想要同步它们,这样每次创建little_vals--时,big_vals都会以双倍的值出现----首先我们创建一个触发器函数,它将--将目标表放置作为参数CREATEORREPLACEFUNCTIONembiggen()RETURNSTRIGGERAS$$BEGINIF(TG_OP='INSERT')THENEXECUTEformat('INSERTINTO%s(key,val)SELECT($1).key,($1).val*2;',TG_ARGV[0])使用新的;万一;返回空值;END;$$LANGUAGEplpgsql;--接下来我们通过触发函数关联并置表-在每个并置位置SELECTrun_command_on_colocated_placements('little_vals','big_vals',$cmd$CREATETRIGGERafter_insertAFTERINSERTON%sFOREACHROWEXECUTEPROCEDUREembiggen(%L)$cmd$);限制多语句事务没有防止死锁的保护措施没有防止中间查询失败和导致的不一致的保护措施。查询结果缓存在内存中;这些函数无法处理非常大的结果集。如果这些功能无法连接到节点,它们会提前失败。你可以做坏事!
